使用dplyr计算多列物种指标的基线倍数变化(R语言)
在R中计算相对于基线的倍数变化
示例数据构造
先复现你提供的数据集,方便后续测试:
df <- data.frame( subject.id = c("id1", "id1", "id1", "id2", "id2", "id2"), timepoint = c("baseline", "2h", "4h", "baseline", "2h", "4h"), treatment = c("A", "A", "A", "B", "B", "B"), Species1 = c(0, 99, 40, 50, 100, 200), Species2 = c(10, 12, 20, 10, 20, 20), Species3 = c(5, 5, 6, 5, 5, 6), SpeciesX = c(5, 6, 5, 5, 6, 5), stringsAsFactors = FALSE )
方法一:使用dplyr(tidyverse工具链)
这是简洁的批量处理方式,适合熟悉tidyverse的用户:
library(dplyr) result <- df %>% # 按受试者分组,确保每个个体仅和自身基线计算 group_by(subject.id) %>% # 批量处理所有以Species开头的列 mutate(across(starts_with("Species"), ~ { # 提取当前分组的基线值 baseline_val <- .[timepoint == "baseline"] # 分情况处理:基线为0时标记err,否则计算倍数 if (baseline_val == 0) { ifelse(timepoint == "baseline", 1, "err") } else { ifelse(timepoint == "baseline", 1, ./baseline_val) } })) %>% # 取消分组 ungroup() # 查看完整结果 print(result, n = Inf)
运行后会得到你需要的结果:基线行所有物种值为1,其他时间点按基线计算倍数,基线为0的列对应非基线行标记为err。
方法二:Base R 实现
如果不想依赖第三方包,可以用原生R代码实现:
# 筛选出所有物种列 species_cols <- grep("^Species", colnames(df), value = TRUE) # 遍历每个受试者 for (subj in unique(df$subject.id)) { # 提取当前受试者的所有数据行 subj_rows <- df$subject.id == subj # 提取当前受试者的基线值 baseline_vals <- df[subj_rows & df$timepoint == "baseline", species_cols] # 遍历每个物种列处理 for (col in species_cols) { base_val <- baseline_vals[[col]] if (base_val == 0) { # 基线为0时,基线行设1,其他行设err df[subj_rows, col] <- ifelse(df[subj_rows, "timepoint"] == "baseline", 1, "err") } else { # 基线非0时,计算倍数,基线行设1 df[subj_rows, col] <- ifelse(df[subj_rows, "timepoint"] == "baseline", 1, df[subj_rows, col] / base_val) } } } print(df, n = Inf)
注意事项
- 确保每个
subject.id只有一条baseline记录,若有重复基线行,需先清理数据(比如用distinct(subject.id, timepoint, .keep_all = TRUE)) - 处理后物种列会混合数值和字符类型(因包含
err),若需保持数值类型,可将"err"替换为NA,后续再按需处理
内容的提问来源于stack exchange,提问作者pepe84
相关产品推荐
相关产品推荐

