如何在DataFrame中为多组列对应用自定义函数?
解决方案:为多组列对应用依赖两列的函数
1. 先明确函数与列对应关系
首先定义处理函数,同时整理好条件列(含yes/no的列)和对应数值列的映射关系:
library(dplyr) # 若用map2方案需加载purrr library(purrr) # 定义你的处理函数 my_fun <- function(a, b) { ifelse(a == "yes", b * 5, b) } # 列对映射:条件列 ↔ 数值列 condition_cols <- c("w", "y") value_cols <- c("x", "z")
2. 方案一:替换原数值列(仅用dplyr)
无需额外依赖,用across结合列索引匹配实现批量处理:
test_df <- tibble(w = c("yes", "no"), x = c(1, 2), y = c("no", "yes"), z = c(4, 5)) test_df %>% mutate( across(all_of(value_cols), ~ my_fun(!!sym(condition_cols[match(cur_column(), value_cols)]), .x)) )
执行后结果:
# A tibble: 2 × 4 w x y z <chr> <dbl> <chr> <dbl> 1 yes 5 no 4 2 no 2 yes 25
3. 方案二:生成新列(保留原列)
如果不想修改原列,而是生成带后缀的新处理列,调整across的.names参数即可:
test_df %>% mutate( across(all_of(value_cols), ~ my_fun(!!sym(condition_cols[match(cur_column(), value_cols)]), .x), .names = "{.col}_scaled") )
结果会新增x_scaled和z_scaled列:
# A tibble: 2 × 6 w x y z x_scaled z_scaled <chr> <dbl> <chr> <dbl> <dbl> <dbl> 1 yes 1 no 4 5 4 2 no 2 yes 5 2 25
4. 方案三:用purrr批量处理(适合大量列对)
如果列对数量极多,用map2批量生成处理结果,逻辑更直观:
# 替换原列 test_df %>% mutate( !!!map2(condition_cols, value_cols, ~ set_names(list(my_fun(!!sym(.x), !!sym(.y))), .y)) ) # 生成新列 test_df %>% mutate( !!!map2(condition_cols, value_cols, ~ set_names(list(my_fun(!!sym(.x), !!sym(.y))), paste0(.y, "_scaled"))) )
为什么你之前的代码出错?
mutate_at(现已被across替代)是针对单个列的操作函数,无法同时传入两列作为参数,因此会出现b未定义的错误——它只能处理单列,找不到第二个参数对应的列。
内容的提问来源于stack exchange,提问作者cahill_598
相关产品推荐
相关产品推荐

