基于dplyr的R语言多分组加权均值计算失效问题
问题分析与解决
嘿,我立刻就发现你代码里的问题啦!你在across()里调用weighted.mean()的方式不对,导致dplyr根本没按你指定的owner和cultivar分组做聚合计算,反而直接对原数据集的每一行执行了计算,所以结果行数才会和原数据一样。
错误根源
在dplyr的summarise()+across()组合中,你需要传递的是函数本身或者函数表达式,而不是直接调用weighted.mean(., w=surface)——这种写法会让R在分组操作之前就把整个列丢进去计算,完全没用到分组逻辑,自然没法实现按组聚合加权均值的需求。
修正后的代码
这里有两种等价的修正方式,你选哪种都可以:
方式1:使用公式风格的函数表达式(更简洁)
results <- original_df %>% group_by(owner, cultivar) %>% summarise( across(where(is.numeric), ~weighted.mean(.x, w = surface)), .groups = "drop" # 可选:聚合后取消分组状态,得到普通数据框 )
方式2:显式定义匿名函数
results <- original_df %>% group_by(owner, cultivar) %>% summarise( across(where(is.numeric), function(x) weighted.mean(x, w = surface)), .groups = "drop" )
关键说明
.x(或者匿名函数里的x)代表across()当前遍历到的数值列,surface则是对应分组内的权重列,这样就能正确按组计算每个数值属性的加权均值了。- 加上
.groups = "drop"是为了在聚合完成后自动取消分组,如果你需要保留分组结构用于后续操作,可以去掉这个参数。
运行效果验证
用你提供的数据集运行修正后的代码,会得到按owner和cultivar唯一组合聚合后的结果,比如owner = "A"且cultivar = 1的组,会把所有对应行的surface作为权重,计算出x1、x2、x3的加权均值,最终结果行数等于owner+cultivar的唯一组合数(你的数据集里是9组)。
内容的提问来源于stack exchange,提问作者Marco Prandi
相关产品推荐
相关产品推荐

