如何用across()替代summarise_at()实现分组加权均值聚合?
使用
across()实现分组加权均值替代summarise_at() 嗨,我来帮你搞定这个问题!你想用across()替换已经被弃用的summarise_at()来计算分组加权均值,关键是要正确传递weighted.mean()的权重参数——直接放函数名是行不通的,得用匿名函数或者公式语法来处理参数传递。
先给你直接能用的正确代码:
library(dplyr) # 定义你的数据框 df <- data.frame( number = c("a","a","a","b","c","c"), y = c(1,2,3,4,1,7), z = c(2,2,6,8,9,1), weight = c(1,1,3,1,2,1) ) # 用across()实现分组加权均值 aggregate <- df %>% group_by(number) %>% summarise(across(c(y, z), ~weighted.mean(.x, w = weight)), .groups = "drop")
关键细节说明:
- 列选择逻辑:
across(c(y, z))明确指定要计算加权均值的目标列,如果你有更多同类型列,也可以用更灵活的选择器,比如where(is.numeric) & !matches("weight"),能自动选中所有数值型且不是权重的列。 - 权重参数传递:
~weighted.mean(.x, w = weight)用公式语法定义了匿名函数,其中.x代表across()当前迭代处理的列,这样就能把weight列作为权重参数传递给weighted.mean()——这正是你之前尝试时缺失的核心步骤,像mean这类无额外参数的函数可以直接写,但带参数的函数必须用这种方式传递参数。
可选优化:给结果列加清晰后缀
如果想让输出的列名更直观,比如加上_weighted_mean后缀,可以这样调整代码:
aggregate <- df %>% group_by(number) %>% summarise(across(c(y, z), list(weighted_mean = ~weighted.mean(.x, w = weight))), .groups = "drop")
这样输出的列名会变成y_weighted_mean和z_weighted_mean,可读性更强。
关于.groups = "drop"
这个参数是可选的,它会在聚合完成后自动取消分组状态;如果你的后续操作还需要保留分组,可以直接去掉这个参数。
内容的提问来源于stack exchange,提问作者titeuf
相关产品推荐
相关产品推荐

