医学数据分析与数据挖掘 · 与讲义 01 配套
学完本节,你将能够:
class() / typeof() 查看类型NA,正确使用 na.rm医学数据里的每一列、每一个值,都对应下面某一类。
numeric / integer → 剂量、体温、天数character → 药名、方剂、证型文本logical → 是否复诊、是否阳性factor → 证型、性别、分组(带 levels)vector → 一列同类型数据list → 病例:ID + 证型 + 药名向量 + 剂量向量data.frame → 行×列表格,最常用变量 = 给数据贴的标签。会创建、会查类型,是后面一切分析的起点。
中医药数据里:剂量、药名、是否复诊、证型 都会存成不同类型。
# 剂量:数值
dose_g <- 10
# 药名:字符
herb <- "黄芪"
# 是否复诊:逻辑
revisit <- TRUE
class(dose_g) # 面向用户的类型,如 "numeric" / "character"
typeof(dose_g) # 底层存储类型,如 "double" / "integer"
str(dose_g) # 结构摘要,调试时常用
class(herb)
class(revisit)
class() 最常用;str() 看结构;typeof() 区分 double / integer。剂量、体温、血压、疗程天数等。熟悉整数/小数与运算,是剂量计算和统计量的基础。
x <- 1
class(x) # "numeric"(默认 double)
i <- 1L # 后缀 L 表示整数
class(i) # "integer"
医学数据里多数用 numeric 即可;需要严格整数时(如计数、频数)用 L。
huangqi_g <- 30
times_per_day <- 2
each_time_g <- huangqi_g / times_per_day # 每次 15g
days <- 15
days %/% 7 # 整除:完整疗程数 = 2
days %% 7 # 取余:剩余天数 = 1
doses <- c(15, 10, 6, 12, 3)
doses + 1
doses / sum(doses) # 每味药占总剂量比例
TRUE / FALSE / NA,表示“是否”类信息。比较与逻辑运算得到一列 TRUE/FALSE,配合下标即可按条件取子集。
age <- c(18, 20, 19, 22)
age >= 20
doses <- c(15, 10, 6, 12, 3)
doses > 10
doses == 10
# & 逐元素(向量化);&& 只看第一个(常用于 if)
c(TRUE, FALSE) & c(TRUE, TRUE) # TRUE FALSE
c(TRUE, FALSE) && c(TRUE, TRUE) # TRUE
if (条件) 里用 && 或 ||,避免只判断第一个元素导致逻辑错误。中药名、方剂名、证型描述等。可做拼接、替换、截取;配合正则与 stringr 可从病案中提取药名、剂量。
herbs <- c("黄芪", "当归", "党参")
nchar(herbs)
paste(herbs, "10g") # 默认空格分隔
paste0(herbs, "_10g") # 无分隔
s <- "当归 10g"
gsub("10g", "12g", s)
substr(s, 1, 2)
as.numeric("12") # 12
as.numeric("12g") # NA(无法解析的部分会变 NA)
as.numeric();含非数字会得 NA。表示“类别”:性别、证型、分组等。带 levels,统计函数会按水平做分组或虚拟变量。
zheng <- factor(c("气虚", "血虚", "气虚", "湿热", "气虚"))
levels(zheng)
table(zheng)
# 文本处理建议先 as.character,否则可能得到 level 编号
z <- factor(c("A", "B", "A"))
paste0("组别=", z) # 可能得到 "组别=1" "组别=2"
paste0("组别=", as.character(z)) # "组别=A" "组别=B"
真实数据常有缺失。有 NA 时 mean、sum 等默认得 NA;需显式用 na.rm = TRUE 或先过滤。
doses2 <- c(10, NA, 6, 12)
is.na(doses2)
sum(is.na(doses2)) # 缺失个数
mean(doses2) # NA
mean(doses2, na.rm = TRUE) # 正常
is.na();NA == NA 结果仍是 NA,不能用来找缺失。vector = 一列同类型;list = 一个病例的全部信息;data.frame = 行×列表格,最常用。
dose_col <- c(10, 12, 9, 15)
patient <- list(
id = "P001", age = 19, zheng = "气虚",
herbs = c("黄芪", "党参", "白术"),
doses = c(30, 15, 12)
)
patient$id
patient$herbs
rx <- data.frame(
patient_id = c("P001", "P002", "P003"),
zheng = factor(c("气虚", "湿热", "血虚")),
formula = c("补中益气汤", "三仁汤", "四物汤"),
herb = c("黄芪", "薏苡仁", "当归"),
dose_g = c(30, 20, 10),
stringsAsFactors = FALSE
)
rx$dose_g
rx[1, ]
rx[, c("patient_id", "formula", "dose_g")]
# 逻辑向量做行下标
rx[rx$dose_g >= 20, ]
# 多条件
rx[rx$dose_g >= 15 & rx$zheng == "气虚", ]
class() / str() 查类型%/% 整除,%% 取余,向量化运算& 逐元素,&& 单值(if 用)paste / paste0,gsub,as.numericlevels(),table(),文本前 as.characteris.na(),na.rm = TRUEd <- c(30, 15, NA, 12, 9),求总剂量(忽略 NA)。h <- c("黄芪", "当归"),拼出 "黄芪_当归"。z <- factor(c("气虚","血虚","气虚")),输出频数。rx 里筛出 dose_g >= 20 的行。