如何避免使用:=,用mutate_at结合case_when改写dplyr代码?
解决
mutate_at结合case_when的动态列赋值问题 我明白你遇到的困扰:之前用:=结合非标准评估的写法会在包检查时触发NOTE,想用mutate_at替代却报错了。下面给你正确的写法,再拆解一下问题出在哪。
正确的mutate_at + case_when实现代码
labels = 'x' dataX <- data.frame(x = colors()) special <- sample(colors(),5) # 核心代码:生成新列names3,保留符合条件的值,其余设为NA dataX <- dataX %>% mutate_at(vars(matches(labels)), list(names3 = ~ dplyr::case_when(. %in% special ~ ., TRUE ~ NA_character_)))
为什么你之前的代码报错?
你的错误写法有两个关键问题:
- 参数格式不对:
mutate_at的第一个参数需要用变量选择器(比如vars())指定目标列,不能直接传命名向量。如果要生成新列,得在list()里用新列名 = ~ 表达式的形式(这是dplyr 0.8版本之后支持的语法)。 case_when语法错误:你把case_when(.) %in% special当成了条件,这完全搞错了case_when的结构——它的正确格式是条件 ~ 对应值,所以应该把. %in% special作为条件,对应的值是.,还要加一个TRUE ~ NA_character_来处理所有不满足条件的情况(否则未匹配的行会得到NULL,导致类型错误)。
其他可选方案对比
- 你自定义的
testx函数是完全可行的,逻辑清晰;但用case_when的写法更贴合dplyr的惯用风格,可读性更强。 - 最初用
:=和UQ(sym())的写法虽然能跑,但因为用到了非标准评估,在包检查时会被标记为NOTE,所以开发包时确实不推荐。
如果你的需求是直接更新原列而不是生成新列,写法可以更简单:
dataX <- dataX %>% mutate_at(vars(matches(labels)), ~ dplyr::case_when(. %in% special ~ ., TRUE ~ NA_character_))
内容的提问来源于stack exchange,提问作者witek
相关产品推荐
相关产品推荐

