【问题标题】:How to take weighted sums of each row of a matrix in R如何在R中获取矩阵每一行的加权和
【发布时间】:2017-03-29 14:59:42
【问题描述】:

我有一个加权股票投资组合和它们的每日回报历史。假设权重不变,我正在尝试计算每个历史日期的投资组合的回报,并用零替换缺失的数据(我正在尝试计算历史 VaR,或 风险价值)。

这是一个简化版:

# portfolio
pfolio = data.frame(ticker = c("stock_a", "stock_b", "stock_noob"), weight = c(0.25, 0.6, 0.15))

# Daily stock returns (with some NA values for one stock):
m = matrix(c(0.0016, 0.0037, -0.0042, -0.0096, -0.0006, -0.0043, -0.0292, -0.0158, 0.0128, 0.0113, 0.0016, 0.0042, NA, NA, 0.0168, -0.0293, 0.0037, -0.0083),
    nrow = 6,
    ncol = 3,
    dimnames = list(c("2017-03-01", "2017-03-02", "2017-03-03", "2017-03-06", "2017-03-07", "2017-03-08"), c("stock_a", "stock_b", "stock_noob"))
)

我正在尝试使用巧妙的 applymapply 方法,但我能想到的最好方法是先清理数据,然后应用 for 循环(讨厌):

m_clean = apply(m, c(1, 2), function(x) if (is.na(x)) 0 else x)
answer = numeric(0)
for (i in 1:nrow(m_clean)) {
    answer = c(answer, sum(m_clean[i, pfolio$ticker] * pfolio$weight))
}

所以主要问题是:什么是干净的单行方式?

【问题讨论】:

    标签: r portfolio


    【解决方案1】:

    你可以这样做:

    m_clean <- ifelse(is.na(m), 0, m) # or 
    m_clean <- m; m_clean[is.na(m_clean)] <- 0
    

    然后

    answer <- apply(m_clean, 1, weighted.mean, w=pfolio$weight) # or
    answer <- colSums(t(m_clean) * pfolio$weight) # or
    answer <- tcrossprod(pfolio$weight, m_clean)
    

    最后是给一个矩阵:

    #> tcrossprod(pfolio$weight, m_clean)
    #     2017-03-01 2017-03-02 2017-03-03 2017-03-06 2017-03-07 2017-03-08
    #[1,]   -0.01712  -0.008555    0.00915   -1.5e-05   0.001365      2e-04
    

    其他解决方案给出了一个命名向量。

    基准测试:

    library("microbenchmark")
    microbenchmark(
      a= apply(m_clean, 1, weighted.mean, w=pfolio$weight),
      c= colSums(t(m_clean) * pfolio$weight),
      p= tcrossprod(pfolio$weight, m_clean),
      m= m_clean %*% pfolio$weight
    )
    # Unit: microseconds
    # expr    min      lq     mean  median      uq    max neval cld
    #    a 49.115 51.0590 54.46379 52.3685 53.9815 99.023   100   c
    #    c 12.688 13.8385 15.02912 14.8460 15.7560 32.366   100  b 
    #    p  5.978  6.8955  7.75998  7.4170  7.8770 30.771   100 a  
    #    m  5.438  6.4330  6.95056  6.8615  7.2710 17.109   100 a  
    

    【讨论】:

    • 谢谢,谢谢你教我microbenchmark 包。如果您反转两个参数,tcrossprod 将给出一个向量而不是矩阵:tcrossprod(m_clean, pfolio$weight),就像您在微基准测试示例中所做的那样。
    猜你喜欢
    • 2013-07-09
    • 2018-07-03
    • 2012-10-28
    • 2011-10-15
    • 2014-07-31
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多