如何在mutate与across中使用带整洁评估的自定义函数
解决方案:将自定义函数适配到
mutate(across)批量处理列 要实现批量处理所有含case的列,你需要调整自定义函数的结构,让它能适配across的工作逻辑——across需要的是作用于单个列向量的函数,而非操作整个数据框的函数。
方法1:重构自定义函数为向量级函数
先定义一个接收列向量和id向量的函数,这样可以直接在across中调用:
# 定义向量级处理函数 times_100_vec <- function(col, id) { case_when( col == "A" ~ paste(col, id, sep = "_"), col == "B" ~ paste(col, id * 100, sep = "_") ) } # 批量处理含"case"的列 my_data %>% mutate(across(contains("case"), ~ times_100_vec(.x, id)))
运行后得到的结果和你之前两次调用times_100的结果完全一致:
# A tibble: 10 × 3 case_one case_two id <chr> <chr> <int> 1 A_1 A_1 1 2 B_200 A_2 2 3 A_3 A_3 3 4 B_400 A_4 4 5 A_5 A_5 5 6 B_600 B_600 6 7 A_7 B_700 7 8 B_800 B_800 8 9 A_9 B_900 9 10 B_1000 B_1000 10
方法2:直接在across中嵌入处理逻辑
如果不想单独定义函数,也可以直接把逻辑写在across的lambda表达式里:
my_data %>% mutate(across(contains("case"), ~ case_when( .x == "A" ~ paste(.x, id, sep = "_"), .x == "B" ~ paste(.x, id * 100, sep = "_") )))
为什么原函数无法直接用在across里?
你原来的times_100函数是面向整个数据框的:它接收数据框和列名参数,返回修改后的数据框。而across的工作机制是遍历指定列,对每一列的向量值应用函数,最终将所有处理后的列组合回原数据框,因此需要的是输入/输出均为向量的函数,而非操作整个数据框的函数。
内容的提问来源于stack exchange,提问作者fschier
相关产品推荐
相关产品推荐

