You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

利用字符串处理结合mutate函数实现R数据框数值校正

问题:R数据框按时间分组校正细菌组数值(减去对应培养基对照)

原始数据

df <- data.frame(
  condition = as.factor(c("ecoli_RPMI", "staph_RPMI", "RPMI", "ecoli_DMEM", "staph_DMEM", "DMEM", "ecoli_RPMI", "staph_RPMI", "RPMI", "ecoli_DMEM", "staph_DMEM", "DMEM")),
  time = as.numeric(c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2)),
  value = as.numeric(c(0.3, 0.3, 0.2, 0.4, 0.4, 0.1, 0.9, 0.8, 0.1, 0.7, 0.8, 0.2))
)

需求说明

按time分组,将每个细菌组(格式如ecoli_RPMI)的value减去同时间点对应单纯培养基对照(如RPMI)的value,生成新列corrected_value,预期结果如下:

data.frame(
  condition = as.factor(c("ecoli_RPMI", "staph_RPMI", "RPMI", "ecoli_DMEM", "staph_DMEM", "DMEM", "ecoli_RPMI", "staph_RPMI", "RPMI", "ecoli_DMEM", "staph_DMEM", "DMEM")),
  time = as.numeric(c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2)),
  value = as.numeric(c(0.3, 0.3, 0.2, 0.4, 0.4, 0.1, 0.9, 0.8, 0.1, 0.7, 0.8, 0.2)),
  corrected_value = as.numeric(c(0.1, 0.1, 0, 0.3, 0.3, 0, 0.8, 0.7, 0, 0.5, 0.6, 0))
)

已尝试方法

曾尝试用group_by结合mutate+case_when的硬编码方式,但扩展性差且未成功,希望通过字符串处理简化实现:

df %>%
  group_by(time)%>%
  mutate(corrected_value = case_when(
  conditions == "ecoli_RPMI" ~ value - value[Conditions == "RPMI"],
  # 其他硬编码条件...
  ))

解决方案

方法1:使用stringr提取培养基名称(推荐,代码更清晰)

library(dplyr)
library(stringr)

df_corrected <- df %>%
  # 提取培养基名称:对照直接取原condition,细菌组取下划线后部分
  mutate(medium = if_else(str_detect(condition, "_"),
                          str_extract(condition, "(?<=_)\\w+"),
                          as.character(condition))) %>%
  # 按时间和培养基分组,确保只匹配同时间的对照
  group_by(time, medium) %>%
  mutate(
    # 同组内,细菌组value减去对照的value,对照自身减为0
    corrected_value = value - value[condition == medium]
  ) %>%
  ungroup() %>%
  select(-medium) # 可选:删除中间辅助列

# 查看结果
print(df_corrected)

方法2:基础R字符串分割(无需额外包)

df_corrected <- df %>%
  mutate(
    medium = sapply(strsplit(as.character(condition), "_"), 
                    function(x) if(length(x) == 2) x[2] else x[1])
  ) %>%
  group_by(time, medium) %>%
  mutate(corrected_value = value - value[condition == medium]) %>%
  ungroup() %>%
  select(-medium)

print(df_corrected)

说明

两种方法核心逻辑一致:

  1. 从condition中提取统一的培养基标识,让细菌组和对应对照归为同一组
  2. 按time+medium分组后,直接用组内对照的value做减法,避免硬编码每个condition,扩展性更强(新增细菌或培养基无需修改代码)

内容的提问来源于stack exchange,提问作者William Hurt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 20:05:39