如何在dplyr::mutate(across())中引用其他列并处理缺失值?
解决dplyr中用across引用静态列生成变化倍数的问题
我来帮你搞定这个问题!你之前的代码出错是因为嵌套了mutate(),across()应该直接放在顶层的mutate()函数里,而且需要合理设置新列的命名规则。另外,R的除法运算本身就会在遇到NA时返回对应NA,完全符合你不想报错的需求,不需要额外处理缺失值。
正确实现代码
library(dplyr) # 初始化你的数据框 df <- data.frame(baseline = c(1,2,3), day1 = c(NA,2,2), day2 = c(2,3,4), day3= c(5,4,6)) # 生成每个day列对应的变化倍数(fc)列 df_with_fc <- df %>% mutate( across( starts_with("day"), # 选中所有以"day"开头的列 ~ .x / baseline, # 计算当前day列与baseline的比值,.x代表当前遍历的day列 .names = "fc_{.col}" # 设置新列命名规则:fc_原列名,比如day1对应fc_day1 ) )
代码解释
across(starts_with("day")):精准筛选出所有以"day"开头的列,避免手动逐个指定列名。~ .x / baseline:这里的.x是across()的内置占位符,代表当前正在处理的day列。因为baseline是数据框的静态列,直接引用即可,不需要用sym()和!!这类引用语法。.names = "fc_{.col}":通过模板字符串定义新列的名称,让每个新生成的变化倍数列对应原day列,可读性更强。
运行结果
执行上述代码后,df_with_fc的输出如下:
baseline day1 day2 day3 fc_day1 fc_day2 fc_day3 1 1 NA 2 5 NA 2.00000 5.0000000 2 2 2 3 4 1.00000 1.50000 2.0000000 3 3 2 4 6 0.66667 1.33333 2.0000000
可以看到,原day列中的NA值在对应的fc列中也保留为NA,完全满足你的需求,没有出现报错或数据截断问题。
额外提示
如果你希望直接替换原有的day列(而不是生成新的fc列),可以去掉.names参数,简化为:
df %>% mutate(across(starts_with("day"), ~ .x / baseline))
不过更推荐保留原列,这样便于后续对比分析。
内容的提问来源于stack exchange,提问作者user42485
相关产品推荐
相关产品推荐

