如何用dplyr的mutate(across())处理列对运算?报错求解
解决dplyr中mutate(across())递归引用的报错问题
报错原因
你遇到的promise already under evaluation: recursive default argument reference or earlier problems?错误,本质是在across()的匿名函数中,直接在.data[[...]]内调用cur_column()触发了延迟求值的递归冲突。dplyr在处理cur_column()和.data引用时,两者的上下文依赖形成了循环,导致无法正常解析列名。
可行解决方法
以下是几种基于mutate(across())的修正方案,均能避免递归求值问题:
方案1:提前存储当前列名
将cur_column()的结果先存入变量,再通过.data引用对应列:
library(dplyr) # 生成示例数据(固定随机数方便复现) set.seed(123) test <- tibble(a = runif(10), b = runif(10)) %>% mutate(across(c(a,b), exp, .names = '{.col}_exp')) # 修正后的代码 test <- test %>% mutate(across(c(a,b), { current_col <- cur_column() .x * .data[[paste0(current_col, '_exp')]] }, .names = '{.col}_mult'))
方案2:使用get()函数替代.data引用
get()能在当前数据框上下文中直接解析列名,避免.data的递归冲突:
test <- test %>% mutate(across(c(a,b), ~ .x * get(paste0(cur_column(), '_exp')), .names = '{.col}_mult'))
方案3:显式定义匿名函数
用标准函数写法替代波浪线~的简写,更清晰地控制求值顺序:
test <- test %>% mutate(across(c(a,b), function(x) { col <- cur_column() x * .data[[paste0(col, '_exp')]] }, .names = '{.col}_mult'))
验证结果
执行上述代码后,数据框会新增a_mult和b_mult列,分别对应a*a_exp和b*b_exp的计算结果,且不会触发报错。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

