在dplyr::summarise中使用拼接字符串作为列名的迭代运算问题
问题原因拆解
你碰到的这个错误很好理解:paste("M", i, sep="")生成的是字符串形式的列名(比如i=1时得到"M1"),但sum()函数需要的是实实在在的数值列向量,直接把字符串丢给sum,它自然会报错——毕竟你没法对一串字符做求和运算嘛。
几种可行的解决办法
下面给你整理了tidyverse生态里的几种解决方案,从适配你原有循环的方式,到更简洁的批量处理方式:
方法1:用.data代词(官方推荐,最直观)
dplyr提供了.data这个特殊代词,专门用来通过字符串引用列。修改你的循环代码就行:
for(i in 1:nrow(ll)) { target_col <- paste("M", i, sep = "") Aone <- tdat %>% group_by(Category) %>% summarize(Msum = sum(.data[[target_col]])) # 这里可以根据需求打印或保存结果,比如 print(Aone) }
.data[[target_col]]会把字符串转换成对应的列引用,sum就能正常计算分组求和了。
方法2:符号转换+非标准求值(早期常用写法)
如果习惯用rlang的工具,可以先把字符串转成符号,再用!!强制求值:
library(rlang) for(i in 1:nrow(ll)) { col_symbol <- sym(paste("M", i, sep = "")) Aone <- tdat %>% group_by(Category) %>% summarize(Msum = sum(!!col_symbol)) }
方法3:用across批量处理(无需循环,更高效)
其实如果你的需求是对所有M开头的列做分组求和,完全不用写循环,用across可以一步到位,这也是tidyverse推荐的批量处理方式:
final_result <- tdat %>% group_by(Category) %>% summarize(across(starts_with("M"), sum, .names = "sum_{col}"))
运行后会直接生成sum_M1和sum_M2两列,分别对应原数据中M1、M2的分组求和结果,输出如下:
# A tibble: 3 × 3 Category sum_M1 sum_M2 <chr> <dbl> <dbl> 1 a 3 21 2 b 10 39 3 c 5 48
内容的提问来源于stack exchange,提问作者Vignesh
相关产品推荐
相关产品推荐

