如何用dplyr的mutate_at或替代方法基于列名数值重算数据框列
批量实现「列名数值 - 列内值」的几种方案
我来帮你搞定这个批量重算的需求!你之前手动指定列的方式虽然可行,但确实不够高效,尤其是列多的时候。下面给你几个实用的批量处理方案,都是不用显式列名的:
推荐方案:用dplyr的across(最新语法)
dplyr现在已经推荐用across替代旧的mutate_at这类函数了,它能更清晰地实现批量列操作:
library(dplyr) df <- data.frame(year = 1:3, "10" = 0:2, "20" = 3:5) colnames(df)[2:3] <- c("10", "20") # 方案1:排除year列,处理其他所有列 df %>% mutate(across(-year, ~ as.numeric(cur_column()) - .x)) # 方案2:精准匹配列名是纯数字的列(更稳妥,避免误处理其他列) df %>% mutate(across(matches("^\\d+$"), ~ as.numeric(cur_column()) - .x))
解释一下:
across(-year):表示选择除了year之外的所有列;如果你的数字列是固定位置,也可以用across(2:3),但用正则匹配更灵活。matches("^\\d+$"):用正则表达式筛选列名是纯数字的列,不管你有多少个数字列,都能自动识别。~ as.numeric(cur_column()) - .x:cur_column()会拿到当前正在处理的列名,转成数值后减去列内的每个值(.x代表列中的单个元素)。
Base R 方案(不用dplyr也能搞定)
如果你不想依赖dplyr,用Base R也能实现同样的效果:
# 先筛选出列名是纯数字的列的索引 num_col_indices <- which(grepl("^\\d+$", colnames(df))) # 批量计算并赋值 df[num_col_indices] <- lapply(num_col_indices, function(i) { as.numeric(colnames(df)[i]) - df[[i]] })
关于你之前mutate_at失败的原因
你之前用mutate_at失败,大概率是因为没有正确获取当前列名。旧版mutate_at可以这么写(不过现在已经被across取代,不推荐使用):
# 旧版mutate_at写法(仅作参考,不推荐) df %>% mutate_at(vars(-year), funs(as.numeric(cur_column()) - .))
不过还是建议用across,它是dplyr团队主推的新语法,更直观也更灵活。
内容的提问来源于stack exchange,提问作者symbolrush
相关产品推荐
相关产品推荐

