如何用tidyverse的mutate(across)遍历多列批量生成新列
完全可以用mutate(across)实现你的需求,以下是两种符合tidyverse风格的简洁实现方案:
方案1:只用dplyr的across+cur_column()实现
这是最简洁的方案,不需要额外引入其他包逻辑:
library(dplyr) library(stringr) df <- df %>% mutate(across( # 匹配所有oldvar1开头的a-i后缀列 .cols = starts_with("oldvar1_"), # 计算逻辑:当前oldvar1列 + 同后缀oldvar2列 - z .fns = ~ .x + get(str_replace(cur_column(), "^oldvar1", "oldvar2")) - z, # 直接生成符合要求的newvar_后缀列名,无需后续改名 .names = "newvar_{str_extract(.col, '_(.+)$', group = 1)}" ))
逻辑说明:
cur_column()可以拿到当前across遍历到的列名,把列名前缀替换为oldvar2就能匹配到同后缀的另一组列.names参数通过正则提取列名的后缀部分,直接生成newvar_a、newvar_i格式的新列名
方案2:搭配purrr批量生成列(更灵活,适合更复杂的多列匹配场景)
如果你的列匹配逻辑更复杂,可以用map遍历后缀批量计算:
library(dplyr) library(purrr) suffix_list <- letters[1:9] df <- df %>% bind_cols( map_dfc(suffix_list, function(suf) { tibble(!!paste0("newvar_", suf) := .data[[paste0("oldvar1_", suf)]] + .data[[paste0("oldvar2_", suf)]] - z) }) )
两种方案的执行效率都远高于手动写for循环反复修改原数据框,也不需要后续批量修改列名。
内容的提问来源于stack exchange,提问作者user17487234
相关产品推荐
相关产品推荐

