在dplyr函数中传递参数至group_by时遇结果异常的问题
问题原因
你遇到的问题是因为!!var直接作用在字符串"b"上时,dplyr会把"b"当成一个固定常量值来分组,而非识别为列名。所以group_by(a, "b")实际是按a的取值和固定字符串"b"分组,最终每个a组内的所有行被归为一组,计算sum(c)时得到a=0的总和3、a=1的总和7,导致结果不符合预期。
解决方案
{{}}是专门针对裸变量名(比如直接传b而非"b")的语法,要处理字符串格式的列名,有两种更合适的方式:
方法1:用sym()转换字符串为符号,配合!!
sym()可以把字符串转换成dplyr能识别的变量符号,再用!!解引用,就能正确指向列名:
myFunc <- function(df, var) { output = df %>% group_by(a, !!sym(var)) %>% mutate(d = sum(c)) return(output) } result2 = myFunc(df, "b") result2$d # 输出 [1,2,3,4]
方法2:用across() + all_of()(推荐)
这是dplyr 1.0.0版本之后推荐的写法,更清晰且支持多列名输入:
myFunc <- function(df, var) { output = df %>% group_by(a, across(all_of(var))) %>% mutate(d = sum(c)) return(output) } result2 = myFunc(df, "b") result2$d # 输出 [1,2,3,4]
如果你的var是包含多个列名的字符串向量(比如c("b", "x")),这种写法无需修改就能直接支持,扩展性更好。
额外说明:如果一定要用{{}}
{{}}本身是为非字符串的裸变量设计的,硬要适配字符串反而绕路,仅作演示:
myFunc <- function(df, var) { var_expr <- rlang::parse_expr(var) output = df %>% group_by(a, {{var_expr}}) %>% mutate(d = sum(c)) return(output) }
实际开发中优先选前两种方法,更简洁直观。
内容的提问来源于stack exchange,提问作者David Mao
相关产品推荐
相关产品推荐

