如何用purrr或across结合mutate按条件生成新数据列
解决方案
方法1:使用dplyr::across()(推荐)
这是最简洁的原生dplyr方案,无需额外依赖purrr即可批量生成目标列:
library(dplyr) df <- tibble(year = c("2018", "2018", "2019", "2019"), observed = c("YES", "NO", "NO", "YES")) # 提取数据中所有唯一的年份 target_years <- unique(df$year) # 批量生成列 df_processed <- df %>% mutate( across( all_of(target_years), ~if_else(observed == "YES" & year == cur_column(), 1, 0), .names = "observed_{.col}" ) ) df_processed
输出结果:
# A tibble: 4 × 4 year observed observed_2018 observed_2019 <chr> <chr> <dbl> <dbl> 1 2018 YES 1 0 2 2018 NO 0 0 3 2019 NO 0 0 4 2019 YES 0 1
all_of(target_years)指定要基于哪些年份生成新列cur_column()获取当前迭代的年份值,用于条件判断.names参数定义新列的命名规则,自动生成observed_年份格式的列名
方法2:使用purrr包实现
如果需要用purrr工具,可以通过map_dfc批量生成列后与原数据绑定:
library(dplyr) library(purrr) df <- tibble(year = c("2018", "2018", "2019", "2019"), observed = c("YES", "NO", "NO", "YES")) target_years <- unique(df$year) # 用map_dfc生成列并合并,再与原数据绑定 df_processed <- df %>% bind_cols( map_dfc(target_years, ~{ col_name <- paste0("observed_", .x) tibble(!!col_name := if_else(observed == "YES" & year == .x, 1, 0)) }) ) df_processed
或者用reduce逐个迭代添加列:
df_processed <- reduce( target_years, function(current_df, y) { current_df %>% mutate(!!paste0("observed_", y) := if_else(observed == "YES" & year == y, 1, 0)) }, .init = df )
内容的提问来源于stack exchange,提问作者nicholas
相关产品推荐
相关产品推荐

