【问题标题】:Aggregate and Weighted Mean in RR中的聚合和加权平均值
【发布时间】:2020-09-03 16:11:45
【问题描述】:

我正在尝试按资产类别计算资产加权回报。对于我的生活,我无法弄清楚如何使用聚合命令来做到这一点。

我的数据框是这样的

dat <- data.frame(company, fundname, assetclass, return, assets)

我正在尝试做类似的事情(不要复制这个,这是错误的):

aggregate(dat, list(dat$assetclass), weighted.mean, w=(dat$return, dat$assets))

【问题讨论】:

    标签: r aggregate


    【解决方案1】:

    对于初学者来说,w=(dat$return, dat$assets)) 是一个语法错误。

    plyr 让这件事变得更容易:

    > set.seed(42)   # fix seed so that you get the same results
    > dat <- data.frame(assetclass=sample(LETTERS[1:5], 20, replace=TRUE), 
    +                   return=rnorm(20), assets=1e7+1e7*runif(20))
    > library(plyr)
    > ddply(dat, .(assetclass),   # so by asset class invoke following function
    +       function(x) data.frame(wret=weighted.mean(x$return, x$assets)))
      assetclass     wret
    1          A -2.27292
    2          B -0.19969
    3          C  0.46448
    4          D -0.71354
    5          E  0.55354
    > 
    

    【讨论】:

    • 它就像一个魅力。第一次尝试时,我将函数中的 x 替换为 dat(为每个资产类别返回相同的数字)。知道为什么这不适用于聚合命令吗?
    • 似乎aggregate 聚合了您希望在两列上进行计算的每一列。我想不久前我使用doBy 或类似的东西——但是,嘿,plyr 使它更容易,并且有其他花里胡哨。
    • 知道这会发生 ;-) 感谢您挥舞着线索。
    【解决方案2】:

    data.table 解决方案,会比plyr 更快

    library(data.table)
    DT <- data.table(dat)
    DT[,list(wret = weighted.mean(return,assets)),by=assetclass]
    ##    assetclass        wret
    ## 1:          A -0.05445455
    ## 2:          E -0.56614312
    ## 3:          D -0.43007547
    ## 4:          B  0.69799701
    ## 5:          C  0.08850954
    

    【讨论】:

    • 我一直想看看 data.table 一段时间了。随着数据库的增长,我想是时候了。欣赏指针!
    【解决方案3】:

    这也可以通过聚合轻松完成。它有助于记住加权平均值的替代方程。

    rw <- dat$return * dat$assets
    dat1 <- aggregate(rw ~ assetclass, data = dat, sum)
    datw <- aggregate(assets ~ assetclass, data = dat, sum)
    dat1$weighted.return <- dat1$rw / datw$assets
    

    【讨论】:

    • 等一下,这没有意义。您实际上是将平均值除以平均样本数。加权平均值是加权值的总和除以权重的总和
    • 有多种方法来做权重,在这种情况下,它是样本的数量,所以它是正确的。权重方程不止一个。在 Dirk 的数据上运行它。
    • mean() 的使用让我很困惑。可能是sum();使用mean() 意味着我们将分子和分母除以nlevels(assetclass)(对于非常大的数据集,平均值可能在数值上更稳定)
    • 是的,对于两个聚合,可以使用sum 重写。结果是一样的,因为相等长度上的两个总和之比等于两个平均值之比(显然平均值中的分母是恒定的)。回想起来,我什至不知道为什么我把平均值放在那里,所以我把它改成了总和。我可能一直在看一本加权平均方程的书,然后选择了一个可行的替代方案。
    【解决方案4】:

    最近发布的collapse 包提供了一套完整的Fast Statistical Functions 在C++ 内部执行分组和加权计算,从而快速解决了这个问题和类似问题(使用加权中值、众数等):

    library(collapse)
    dat <- data.frame(assetclass = sample(LETTERS[1:5], 20, replace = TRUE), 
                      return = rnorm(20), assets = 1e7+1e7*runif(20))
    
    # Using collap() function with fmean, which supports weights: (by default weights are aggregated using the sum, which is prevented using keep.w = FALSE)
    collap(dat, return ~ assetclass, fmean, w = ~ assets, keep.w = FALSE)
    ##   assetclass     return
    ## 1          A -0.4667822
    ## 2          B  0.5417719
    ## 3          C -0.8810705
    ## 4          D  0.6301396
    ## 5          E  0.3101673
    
    # Can also use a dplyr-like workflow: (use keep.w = FALSE to omit sum.assets)
    library(magrittr)
    dat %>% fgroup_by(assetclass) %>% fmean(assets)
    ##   assetclass sum.assets     return
    ## 1          A   80683025 -0.4667822
    ## 2          B   27411156  0.5417719
    ## 3          C   22627377 -0.8810705
    ## 4          D  146355734  0.6301396
    ## 5          E   25463042  0.3101673
    
    # Or simply a direct computation yielding a vector:
    dat %$% fmean(return, assetclass, assets)
    ##          A          B          C          D          E 
    ## -0.4667822  0.5417719 -0.8810705  0.6301396  0.3101673 
    

    【讨论】:

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