如何在R中按年份计算Country a、b列的加权均值?
R语言按年份计算a、b列加权均值(修正dplyr报错)
需求说明
基于给定的data.frame,按YEAR_CALENDAR分组,计算a、b两列的加权平均值,权重由weights列提供。
数据示例
df <- data.frame( YEAR_CALENDAR=c(2020, 2020, 2020, 2020, 2020, 2021, 2021, 2021, 2021, 2021), age_group=c("15-29", "30-44", "45-59", "60-74", "Over 75", "15-29", "30-44", "45-59", "60-74", "Over 75"), a=c(3.85, 3.66, 3.76, 2.70, 3.10, 4.32, 4.64, 3.67, 3.45, 4.56), b=c(3.56, 3.67, 3.72, 3.89, 4.23, 4.28, 4.27, 3.12, 3.46, 3.97), weights=rep(c(0.3333784699, 0.2890995261, 0.2161137441, 0.1203791469, 0.04150304671), 2))
初始报错问题
原代码尝试用mutate+across计算加权乘积时触发non-numeric argument to binary operator错误:
new_df <- df %>% mutate(across(3:4, .*df$weights))
报错原因
across内部语法错误:.不能直接用于乘法运算,需用函数形式~ .x * weights,其中.x指代当前遍历的列- 不应使用
df$weights引用列,在dplyr管道中直接用列名weights即可,符合上下文引用规则
可行解决方案
方案1:直接用weighted.mean函数一步计算(推荐)
利用R内置的weighted.mean函数,结合group_by+summarise+across直接得到各年份的加权均值:
library(dplyr) weighted_mean_df <- df %>% group_by(YEAR_CALENDAR) %>% summarise( across(c(a, b), ~ weighted.mean(.x, weights)), .groups = "drop" # 取消分组状态 ) # 输出结果 print(weighted_mean_df)
方案2:分步计算加权乘积再汇总
先通过mutate计算a、b与权重的乘积,再按年份求和后除以权重总和:
library(dplyr) # 第一步:计算加权乘积 new_df <- df %>% mutate(across(c(a, b), ~ .x * weights, .names = "weighted_{.col}")) # 第二步:按年份汇总计算加权均值 weighted_mean_df <- new_df %>% group_by(YEAR_CALENDAR) %>% summarise( a = sum(weighted_a) / sum(weights), b = sum(weighted_b) / sum(weights), .groups = "drop" ) # 输出结果 print(weighted_mean_df)
两种方案得到的结果完全一致,方案1更简洁高效。
内容的提问来源于stack exchange,提问作者rnoob
相关产品推荐
相关产品推荐

