【问题标题】:Calculate weights based on variance of multiple columns and calculate weighted sum根据多列的方差计算权重并计算加权和
【发布时间】:2020-06-26 07:49:10
【问题描述】:

我想在 R 中执行以下操作 -

  1. 计算列的方差
  2. 计算每一列的权重:variance[i]/sum(variances)
  3. 计算加权和

数据框(例如)将是

structure(list(Date = structure(c(18436, 18437, 18438, 18439), class = "Date"), 
    `BIB_Level 1` = c(261, 278, 113, 187), `BIB_Level 2` = c(230, 
    141, 280, 132), `BIB_Level 3` = c(242, 176, 149, 274)), .Names = c("Date", 
"BIB_Level 1", "BIB_Level 2", "BIB_Level 3"), row.names = c(NA, 
-4L), class = "data.frame")

示例:示例中各列的方差为

> sapply(wideDf[,-1],FUN = var,na.rm=T)
BIB_Level 1 BIB_Level 2 BIB_Level 3 
   5720.917    5110.917    3332.250

权重是:

> sapply(wideDf[,-1],FUN = var,na.rm=T)/sum(sapply(wideDf[,-1],FUN = var,na.rm=T))
BIB_Level 1 BIB_Level 2 BIB_Level 3 
  0.4039031   0.3608364   0.2352605 

第一行的加权总和为

> (261*0.4039031)+(230*0.3608364)+(242*0.2352605)
[1] 245.3441

我需要一个附加到数据框的加权和列。

我怎样才能把它写成一段代码?

谢谢

【问题讨论】:

    标签: r sumproduct


    【解决方案1】:

    目前尚不清楚为什么这一切都必须在一个代码块中,但以下内容可以做到。

    请注意,矩阵上var(协方差函数)结果的对角线条目确实是方差。但值得计算一次而不是多次。

    通过转置wideDf,您可以使用R 的按列操作快速将每一列(最初是每一行)与权重向量相乘。

    wideDf$weighted_sums <- colSums(t(wideDf[, -1]) * diag(var(wideDf[, -1], na.rm = TRUE)) / sum(diag(var(wideDf[, -1], na.rm = TRUE))))
    wideDf
            Date BIB_Level 1 BIB_Level 2 BIB_Level 3 weightedSums
    1 2020-06-23         261         230         242     245.3441
    2 2020-06-24         278         141         176     204.5688
    3 2020-06-25         113         280         149     181.7291
    4 2020-06-26         187         132         274     187.6217
    

    【讨论】:

      【解决方案2】:

      您可以将sweeprowSums 一起使用:

      val <- sapply(wideDf[,-1],FUN = var,na.rm=TRUE)
      weight <- val/sum(val)
      wideDf$weighted_sum <- rowSums(sweep(wideDf[-1], 2, weight, `*`))
      wideDf
      
      #        Date BIB_Level 1 BIB_Level 2 BIB_Level 3 weighted_sum
      #1 2020-06-23         261         230         242     245.3441
      #2 2020-06-24         278         141         176     204.5688
      #3 2020-06-25         113         280         149     181.7291
      #4 2020-06-26         187         132         274     187.6217
      

      或者转置数据乘以weight 并取列的总和。

      wideDf$weighted_sum <- colSums(t(wideDf[-1]) * weight)
      

      【讨论】:

        猜你喜欢
        • 2022-01-16
        • 1970-01-01
        • 1970-01-01
        • 2021-02-18
        • 1970-01-01
        • 1970-01-01
        • 2012-04-20
        • 2021-11-14
        • 2018-03-10
        相关资源
        最近更新 更多