如何基于元数据框的变量类型对数据框执行分组差异化聚合?
问题解决:按变量类型差异化聚合分组数据
问题背景
现有数据框df,需按Group列分组后,依据元数据框metaVar中定义的变量类型,对不同类型变量执行差异化聚合:
- 类型为
stock的变量:求和 - 类型为
ratio的变量:求均值
原尝试使用dplyr的summarise结合两个across函数实现,但代码报错。
错误原因
原代码中where(names(.) %in% ...)的写法有误:where()函数用于基于列的属性(如是否为数值型)筛选列,而直接通过列名筛选时,无需嵌套where(),应使用all_of()来引用外部定义的列名向量,避免dplyr列选择上下文的解析问题。
正确实现方法
方法1:拆分变量类型,分别用across + all_of
先从metaVar提取两类变量的列名,再在across中用all_of()指定列并执行对应聚合函数:
# 提取两类变量的列名 stock_vars <- metaVar$Var[metaVar$Type == "stock"] ratio_vars <- metaVar$Var[metaVar$Type == "ratio"] # 分组聚合 groupDF <- df %>% group_by(Group) %>% summarise( across(all_of(stock_vars), sum, na.rm = TRUE), across(all_of(ratio_vars), mean, na.rm = TRUE) ) %>% ungroup
方法2:通过命名函数列表批量匹配
将metaVar转换为「变量名-聚合函数」的映射列表,用单个across自动匹配执行,更简洁:
# 构建变量到聚合函数的映射列表 agg_funs <- metaVar %>% tibble::deframe() %>% dplyr::recode(stock = "sum", ratio = "mean") %>% purrr::map(get) # 将函数名转为实际函数 # 分组聚合 groupDF <- df %>% group_by(Group) %>% summarise(across(all_of(names(agg_funs)), ~agg_funs[[cur_column()]](., na.rm = TRUE))) %>% ungroup
方法3:单across内通过条件判断执行不同函数
在单个across中,根据当前列名对应的类型动态选择聚合函数:
groupDF <- df %>% group_by(Group) %>% summarise(across(c(stock_vars, ratio_vars), ~{ var_type <- metaVar$Type[metaVar$Var == cur_column()] if(var_type == "stock") sum(., na.rm = TRUE) else mean(., na.rm = TRUE) })) %>% ungroup
验证结果
运行上述任意代码后,groupDF会按Group分组,正确输出stock类型变量的求和结果与ratio类型变量的均值结果。
内容的提问来源于stack exchange,提问作者pgourdon
相关产品推荐
相关产品推荐

