如何用dplyr在R中为数据框对应列减去命名向量值?
解决方案:使用dplyr为data.frame指定列减去对应常量向量值
你的问题核心是在dplyr::across的处理表达式中,错误使用了.col来引用当前列名——.col是across函数的外部列选择参数,在~定义的处理逻辑内部,需要用cur_column()函数来获取当前正在处理的列名。
修正后的完整代码
library(dplyr) set.seed(1) toy_df <- data.frame(Patient.ID = letters[1:5], Patient.Age = rnorm(5,35,4), Protein.A = rnorm(5,100,10), Protein.B = rnorm(5,100,10), Protein.D = rnorm(5,100,10), Protein.E = rnorm(5,100,10)) # 计算中位数绝对偏差向量 medianDeviation <- apply(X = toy_df[,grepl("^Protein\\.", names(toy_df))], MARGIN = 2, FUN = function(x) median(x) + (2*mad(x))) # 正确的dplyr实现 result <- toy_df %>% mutate(across(all_of(names(medianDeviation)), ~ .x - medianDeviation[cur_column()]))
关键细节说明
all_of(names(medianDeviation)):严格匹配medianDeviation向量的列名,避免列名不匹配导致的错误cur_column():在across的处理逻辑内部,动态获取当前操作的列名,以此精准索引medianDeviation向量中的对应值.x:在~表达式中代表当前列的所有值(也可用.替代,.x可读性更强)
全dplyr风格的偏差向量计算(可选)
如果想全程用dplyr语法替代apply,可以这样计算medianDeviation:
medianDeviation <- toy_df %>% select(starts_with("Protein.")) %>% summarise(across(everything(), ~ median(.x) + 2*mad(.x))) %>% unlist() %>% set_names(names(.))
内容的提问来源于stack exchange,提问作者Luiz Gustavo
相关产品推荐
相关产品推荐

