如何通过省略号参数将列名传递给is.na函数在dplyr中使用
问题原因与解决方案
报错产生的原因
你遇到的报错本质是dplyr非标准评估机制的适配问题:
- 你在
mutate中直接将...传递给is.na()时,is.na()无法将...解析为你传入的分组列,实际作用的是...这个参数容器对象,该对象属于closure(闭包/函数类)类型,不符合is.na()的入参要求,因此抛出类型错误。 - 补充说明
my_fun1不符合预期的原因:dplyr的group_by默认会将分组列的NA值作为独立分组处理,因此会给NA对应的行计算该组的均值,而不是返回你期望的NA值。
修复方案
如果你需要支持传入任意数量的分组列,只要任意分组列值为NA时avg就返回NA,可以用cur_group()获取当前分组的所有值来判断:
my_fun_fixed <- function(.data, ...) { .data %>% group_by(...) %>% mutate( # 判断当前分组的分组列是否存在NA group_has_na = any(is.na(cur_group())), avg = if_else(group_has_na, NA_real_, mean(value)) ) %>% select(-group_has_na) # 移除辅助判断列 } # 调用测试,返回结果和你手动写的逻辑完全一致 my_fun_fixed(df, id)
如果你确定只需要传入单个分组列,也可以用卷曲运算符{{}}实现更简洁的写法:
my_fun_single <- function(.data, group_col) { .data %>% group_by({{group_col}}) %>% mutate(avg = if_else(is.na({{group_col}}), NA_real_, mean(value))) } # 调用测试 my_fun_single(df, id)
内容的提问来源于stack exchange,提问作者nicholas
相关产品推荐
相关产品推荐

