如何使用tidy evaluation在mutate中动态创建列?
问题定位
你编写的代码存在两个核心问题:
- 对tidy evaluation的规则理解有误:匿名运算里的
./.x代表当前处理列的全部单元格数值,无法从中提取列名文本,原本尝试用.拼接.Length后缀的逻辑,实际会把整列的所有数值拼进字符串,根本生成不了合法的列引用 - 使用了已进入软弃用状态的
mutate_at接口,长期维护性不足
可运行的实现代码
iris %>% rename(Sepal = Sepal.Width, Petal = Petal.Width) %>% mutate( across( .cols = c(Sepal, Petal), .names = "{.col}_test", .fns = ~ .x / !!sym(paste0(cur_column(), ".Length")) ) )
实现逻辑说明
cur_column()是dplyr提供的列级遍历专用接口,会直接返回当前正在处理的列的字符串名称:遍历到Sepal列时返回"Sepal",遍历到Petal列时返回"Petal"- 拼接得到分母列的字符串名后,通过
sym()将字符串转为可被dplyr识别的符号对象,搭配!!做强制求值,即可正确引用对应的分母列完成运算 across的.names参数会按规则自动生成新变量名,最终输出的Sepal_test、Petal_test列,和你原本用list(test = ~ xxx)期望的命名逻辑完全一致
避坑提示
不要试图从.x对应的数值向量里提取列名属性,普通列遍历场景下的.x是纯数值向量,不携带列名字符串属性,硬做提取操作只会触发报错或者产出不符合预期的计算结果。
内容的提问来源于stack exchange,提问作者spazznolo
相关产品推荐
相关产品推荐

