在mutate()中使用weighted.mean()计算行加权均值的技术问题求助
解决行级加权均值计算问题
你遇到的问题核心是weighted.mean()默认是对整个输入的向量/矩阵计算全局加权平均,而不是按行单独计算,所以最终得到的是一个常量并广播到所有行。下面给你几种可行的解决方案:
方法1:用rowwise()实现直观的行级计算
如果你希望保留weighted.mean()的na.rm功能,同时按行计算,可以先通过rowwise()将数据框按行分组,这样后续的mutate会逐行执行:
library(tidyverse) set.seed(2021) df <- tibble(x = rnorm(10,0,5), y = rnorm(10,0,10)) # 按行计算加权均值 df <- df %>% rowwise() %>% mutate(z = weighted.mean(c(x, y), c(0.2, 0.8), na.rm = TRUE)) %>% ungroup() # 记得取消行分组,避免影响后续操作
这种方法逻辑清晰,适合小数据集,完全匹配你对na.rm功能的需求。
方法2:手动计算(大数据集更高效)
加权均值本质上是x*权重1 + y*权重2,如果你的数据没有缺失值,直接手动计算会比rowwise()快很多:
df <- df %>% mutate(z = x*0.2 + y*0.8)
如果需要处理缺失值,且和weighted.mean(na.rm=TRUE)行为一致(即忽略缺失值后重新归一化权重),可以手动模拟这个逻辑:
df <- df %>% mutate( # 计算各变量的加权值,缺失值则权重和值都记为0 x_weighted = ifelse(is.na(x), 0, x * 0.2), y_weighted = ifelse(is.na(y), 0, y * 0.8), # 计算有效权重总和 total_weight = ifelse(is.na(x), 0, 0.2) + ifelse(is.na(y), 0, 0.8), # 计算最终加权均值,有效权重为0时返回NA z = ifelse(total_weight == 0, NA, (x_weighted + y_weighted)/total_weight) ) %>% select(-x_weighted, -y_weighted, -total_weight) # 移除中间变量
方法3:用apply()按行处理
另一种经典的按行操作方式是使用apply()函数,指定按行(第二个参数为1)执行计算:
df$z <- apply(df[, c("x", "y")], 1, function(row) { weighted.mean(row, c(0.2, 0.8), na.rm = TRUE) })
这种方法不需要依赖dplyr的分组,代码简洁,性能介于前两者之间。
内容的提问来源于stack exchange,提问作者bachflip
相关产品推荐
相关产品推荐

