使用tidyverse对含缺失值的列批量计算加权均值
批量计算带NA过滤的加权均值
需求说明
现有数据集foo,每行包含样本量n及变量x1、x2、x3。需要为每个变量计算加权均值,权重为n/sum(n),且计算时要排除对应变量为NA的n值,要求批量完成而非逐个手动计算。
数据集定义:
foo <- data.frame(n = c(99,12,53,12,19,21), x1 = c(5,2,6,NA,13,78), x2 = c(15,NA,60,NA,3,7), x3 = c(2,7,4,9,4,2))
解决方案
可以利用dplyr的across(替代旧版的summarise_at)批量处理,逻辑和手动计算完全一致且更高效。
方法1:自定义函数+across
先定义一个自动过滤NA值的加权均值函数,再批量作用于目标变量:
library(dplyr) # 自定义函数:自动排除对应变量为NA的样本量,计算加权均值 weighted_mean_na_filter <- function(x, n) { valid_rows <- !is.na(x) sum(x[valid_rows] * n[valid_rows]) / sum(n[valid_rows]) } # 批量计算所有x开头变量的加权均值 foo %>% summarise(across(starts_with("x"), ~weighted_mean_na_filter(.x, n)))
运行输出结果:
x1 x2 x3 1 16.664286 22.76923 4.072727
方法2:直接在across中编写逻辑(无需自定义函数)
如果不想单独定义函数,可将逻辑直接写入匿名函数:
foo %>% summarise(across(starts_with("x"), ~{ valid_n <- n[!is.na(.x)] sum(.x[!is.na(.x)] * valid_n) / sum(valid_n) }))
结果验证
对比手动计算结果:
- x1手动计算值为
16.664286,与批量计算一致 - x2手动计算值为
22.76923,与批量计算一致
补充说明
- 核心逻辑:仅使用对应变量非NA的
n计算权重总和,完全匹配你手动drop_na后计算的逻辑 starts_with("x")会自动匹配所有以x开头的变量,后续新增x4、x5等变量时,代码无需修改即可自动处理
内容的提问来源于stack exchange,提问作者user111024
相关产品推荐
相关产品推荐

