如何在R的summarise中根据条件选择性生成聚合列?
问题:在dplyr的summarize中根据条件选择性生成汇总列
我现在的处理逻辑是先通过summarize批量生成所有需要的汇总列,再逐个根据条件删除不需要的列;另一种思路是单独生成每一列再用join合并,但这种方式效率更低。
当前代码如下:
Data <- Data %>% group_by_at(group_by_Vektor) %>% summarize(var_1 = sum(var_1), var_2 = sum(var_2), ... var_n = sum(var_n), .groups = 'drop') if (!condition_1) { Data <- select(Data, -var_1) } if (!condition_2) { Data <- select(Data, -var_2) } ... if (!condition_n) { Data <- select(Data, -var_n) }
我希望能直接在summarize步骤里根据条件决定是否生成对应列,实现类似下面的写法:
Data <- Data %>% group_by_at(group_by_Vektor) %>% summarize(if(condition_1, var_1 = sum(var_1)), if(condition_2, var_2 = sum(var_2), ... if(condition_n, var_n = sum(var_n)), .groups = 'drop')
解决方案
方法1:结合across筛选变量后批量汇总
先根据条件筛选出需要汇总的变量,再用across批量执行汇总操作,无需后续删列步骤:
# 筛选需要汇总的变量(自动过滤不符合条件的变量) vars_to_summarize <- c( if (condition_1) "var_1", if (condition_2) "var_2", # 依次添加其他变量的条件判断 if (condition_n) "var_n" ) %>% na.omit() # 移除空值(即不满足条件的变量) Data <- Data %>% group_by_at(group_by_Vektor) %>% summarize(across(all_of(vars_to_summarize), sum), .groups = 'drop')
方法2:构建表达式列表后批量传入summarize
用rlang包的quo构建汇总表达式,再通过!!!(非标准求值)传入summarize,适合每个变量有不同汇总逻辑的场景:
library(rlang) # 初始化表达式列表 sum_exprs <- list() # 根据条件添加对应汇总表达式 if (condition_1) sum_exprs[["var_1"]] <- quo(sum(var_1)) if (condition_2) sum_exprs[["var_2"]] <- quo(sum(var_2)) # 依次添加其他变量的条件判断 if (condition_n) sum_exprs[["var_n"]] <- quo(sum(var_n)) Data <- Data %>% group_by_at(group_by_Vektor) %>% summarize(!!!sum_exprs, .groups = 'drop')
两种方法都能直接在summarize阶段生成符合条件的列,避免后续反复调用select删列,代码更简洁高效。
内容的提问来源于stack exchange,提问作者Roland
相关产品推荐
相关产品推荐

