01 · R 语言数据类型与运算

医学数据分析与数据挖掘 · 与讲义 01 配套

← 演示列表 · 进入讲义

本节目标

学完本节,你将能够:

  • 用变量存储剂量、药名、证型等,并用 class() / typeof() 查看类型
  • 对数值做四则、取余、向量化运算,用于剂量与疗程计算
  • 用逻辑型与比较运算写出筛选条件,配合下标取子集
  • 处理字符(拼接、替换、截取)与因子(levels、频数),并避开常见坑
  • 识别并处理缺失值 NA,正确使用 na.rm
  • 区分 vector、list、data.frame,能构建和索引处方表

大纲

  1. 变量与类型检查
  2. 数值:剂量与运算
  3. 逻辑:筛选条件
  4. 字符:药名与文本
  5. 因子:证型分类
  6. 缺失值:NA
  7. 容器:vector / list / data.frame
  8. 练习与小结

R 数据类型总览

医学数据里的每一列、每一个值,都对应下面某一类。

原子类型(单值/向量)

  • numeric / integer → 剂量、体温、天数
  • character → 药名、方剂、证型文本
  • logical → 是否复诊、是否阳性
  • factor → 证型、性别、分组(带 levels)

容器类型(多列/复杂结构)

  • vector → 一列同类型数据
  • list → 病例:ID + 证型 + 药名向量 + 剂量向量
  • data.frame → 行×列表格,最常用
先掌握原子类型与运算,再组合成 data.frame 做真实分析。

1 变量与类型检查

变量 = 给数据贴的标签。会创建、会查类型,是后面一切分析的起点。

1.1 创建变量

中医药数据里:剂量药名是否复诊证型 都会存成不同类型。

# 剂量:数值
dose_g <- 10

# 药名:字符
herb <- "黄芪"

# 是否复诊:逻辑
revisit <- TRUE

1.2 类型查看函数

class(dose_g)   # 面向用户的类型,如 "numeric" / "character"
typeof(dose_g)  # 底层存储类型,如 "double" / "integer"
str(dose_g)     # 结构摘要,调试时常用

class(herb)
class(revisit)
class() 最常用;str() 看结构;typeof() 区分 double / integer。

2 数值:剂量与运算

剂量、体温、血压、疗程天数等。熟悉整数/小数与运算,是剂量计算和统计量的基础。

2.1 整数与小数

x <- 1
class(x)     # "numeric"(默认 double)

i <- 1L      # 后缀 L 表示整数
class(i)     # "integer"

医学数据里多数用 numeric 即可;需要严格整数时(如计数、频数)用 L

2.2 常用运算(剂量 / 疗程)

huangqi_g <- 30
times_per_day <- 2
each_time_g <- huangqi_g / times_per_day   # 每次 15g

days <- 15
days %/% 7   # 整除:完整疗程数 = 2
days %% 7    # 取余:剩余天数 = 1

2.3 向量化运算

doses <- c(15, 10, 6, 12, 3)
doses + 1
doses / sum(doses)   # 每味药占总剂量比例
R 的运算支持向量化,可对整组数据逐元素计算,无需写循环。

3 逻辑:筛选条件

TRUE / FALSE / NA,表示“是否”类信息。比较与逻辑运算得到一列 TRUE/FALSE,配合下标即可按条件取子集。

3.1 比较运算

age <- c(18, 20, 19, 22)
age >= 20

doses <- c(15, 10, 6, 12, 3)
doses > 10
doses == 10

3.2 & 与 && 的区别

# & 逐元素(向量化);&& 只看第一个(常用于 if)
c(TRUE, FALSE) & c(TRUE, TRUE)   # TRUE FALSE
c(TRUE, FALSE) && c(TRUE, TRUE) # TRUE
注意if (条件) 里用 &&||,避免只判断第一个元素导致逻辑错误。

4 字符:药名与文本

中药名、方剂名、证型描述等。可做拼接、替换、截取;配合正则与 stringr 可从病案中提取药名、剂量。

4.1 拼接与长度 · 4.2 替换与截取

herbs <- c("黄芪", "当归", "党参")
nchar(herbs)
paste(herbs, "10g")      # 默认空格分隔
paste0(herbs, "_10g")    # 无分隔

s <- "当归 10g"
gsub("10g", "12g", s)
substr(s, 1, 2)

4.3 字符转数值

as.numeric("12")     # 12
as.numeric("12g")    # NA(无法解析的部分会变 NA)
从 Excel 或文本读入的“数字”常是字符,做运算前需 as.numeric();含非数字会得 NA。

5 因子:证型分类

表示“类别”:性别、证型、分组等。带 levels,统计函数会按水平做分组或虚拟变量。

5.1 levels 与频数

zheng <- factor(c("气虚", "血虚", "气虚", "湿热", "气虚"))
levels(zheng)
table(zheng)

5.2 因子坑

# 文本处理建议先 as.character,否则可能得到 level 编号
z <- factor(c("A", "B", "A"))
paste0("组别=", z)           # 可能得到 "组别=1" "组别=2"
paste0("组别=", as.character(z))  # "组别=A" "组别=B"
常见坑 因子本质存的是整数索引,拼接、正则等操作前先转字符。

6 缺失值:NA

真实数据常有缺失。有 NA 时 mean、sum 等默认得 NA;需显式用 na.rm = TRUE 或先过滤。

6.1 is.na · 6.2 na.rm

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,不能用来找缺失。

7 容器:vector / list / data.frame

vector = 一列同类型;list = 一个病例的全部信息;data.frame = 行×列表格,最常用。

7.1 vector · 7.2 list

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

7.3 data.frame(行=观测,列=变量)

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")]

7.4 按条件筛选行

# 逻辑向量做行下标
rx[rx$dose_g >= 20, ]

# 多条件
rx[rx$dose_g >= 15 & rx$zheng == "气虚", ]
把“比较运算”得到的 TRUE/FALSE 用在行下标里,就是条件筛选。

小结 · 速查

  • class() / str() 查类型
  • 数值:%/% 整除,%% 取余,向量化运算
  • 逻辑:& 逐元素,&& 单值(if 用)
  • 字符:paste / paste0gsubas.numeric
  • 因子:levels()table(),文本前 as.character
  • 缺失:is.na()na.rm = TRUE
  • 容器:vector 同类型,list 多成分,data.frame 行列索引

8 练习

  1. d <- c(30, 15, NA, 12, 9),求总剂量(忽略 NA)。
  2. h <- c("黄芪", "当归"),拼出 "黄芪_当归"
  3. 因子 z <- factor(c("气虚","血虚","气虚")),输出频数。
  4. rx 里筛出 dose_g >= 20 的行。
要点:区分 vector / data.frame / list,掌握 is.na() 与向量化运算。

谢谢

返回演示列表 · 进入 01 讲义