【问题标题】:Weighted means for groups in r - using aggregate and weighted.mean functions togetherr 中组的加权平均值 - 一起使用聚合和 weighted.mean 函数
【发布时间】:2020-10-08 11:13:52
【问题描述】:

我正在尝试跨所有数值变量计算组变量 X1 的加权平均值,这是一些示例数据

set.seed(123)
X1=rep(c("A", "B", "C"), each = 4)
Y1=as.numeric(seq(1,12,by=1))
Y2=sample(1:5,12,TRUE)
Y3=sample(10:20,12,TRUE)
wgt <- abs(rnorm(12)*10)
df <- data.frame(X1,Y1,Y2,Y3,wgt)
            

这是我用来计算 X1 的常规平均值的代码

aggregate( df[, sapply(df, is.numeric)] , by=list(df$X1) , FUN=mean, na.rm=TRUE)

我想计算权重平均值,权重变量是wgt。我尝试了这两个代码,但都没有工作。我尝试了许多不同的方法,但没有任何效果。

aggregate( df[, sapply(df, is.numeric)] , by=list(df$X1) , FUN=weighted.mean(x, w=df$wgt), na.rm = TRUE)
aggregate( df[, sapply(df, is.numeric)] , by=list(df$X1) , FUN=weighted.mean, w=df$wgt, na.rm = TRUE)

我无法调整 weighted.mean 函数。谁能告诉我哪里出错了?在这种情况下甚至可以使用此功能吗? 任何帮助是极大的赞赏。谢谢

【问题讨论】:

    标签: r


    【解决方案1】:

    这是一种使用by() 调用的aggregate 计算加权均值的方法。

    res <- by(df, df$X1, function(DF){
      aggregate(cbind(Y1, Y2, Y3) ~ X1, DF, function(y, w) 
        weighted.mean(y, w = DF[['wgt']], na.rm = TRUE))
    })
    do.call(rbind, res)
    #  X1        Y1       Y2       Y3
    #A  A  2.152503 2.633935 18.93457
    #B  B  6.677851 3.589251 16.90102
    #C  C 10.194695 2.638378 16.70958
    

    【讨论】:

    • 而不是用 cbind(Y1, Y2, Y3) 指定每个变量。是否可以像我使用 is.numeric() 函数一样选择所有数值变量?
    • @H.Cheung 我不相信这是可能的,或者至少不会更简单。这是公式的 LHS 的问题。请参阅Chuck P's answer 了解可以做到这一点的 dplyr 解决方案。
    【解决方案2】:

    您可以使用outer 横向应用weighted.mean。

    gr <- c("A", "B", "C"); ys <- c("Y1", "Y2", "Y3")
    WF <- Vectorize(function(x, y) with(df[df$X1 %in% x, ], weighted.mean(get(y), wgt)))
    res <- `dimnames<-`(outer(gr, ys, WF), list(gr, ys))
    res
    #          Y1       Y2       Y3
    # A  2.152503 2.633935 18.93457
    # B  6.677851 3.589251 16.90102
    # C 10.194695 2.638378 16.70958
    

    【讨论】:

    • 我尝试了您的代码,但它没有提供您最初发布的答案。我将编辑添加到您的帖子中。要手动计算加权平均值,需要将其乘以权重,然后除以相应 X1 组的权重之和,以获得加权平均值。将其乘以权重只会使平均值膨胀。无论如何感谢您的宝贵时间
    • @H.Cheung 非常感谢您的指点!显然我对控制台上的几个结果感到恼火,并且太快地将错误的结果分配给代码。我建议使用 outer 的替代解决方案,请参阅编辑!
    • 效果很好。这是一种有趣的方式。再次感谢您
    【解决方案3】:

    这是一个dplyr 解决方案,它返回与@Rui 相同的答案。根据要求,这将对所有数字变量进行操作,无论其列名如何。

    df %>% 
       group_by(X1) %>% 
       summarise(across(where(is.numeric), 
                        ~ weighted.mean(.x, wgt), 
                        .names = "weighted_mean_{.col}"))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-01
      • 1970-01-01
      • 2021-08-31
      • 1970-01-01
      • 1970-01-01
      • 2014-08-09
      • 2021-08-12
      相关资源
      最近更新 更多