【问题标题】:Efficient calculation of matrix cumulative standard deviation in rr中矩阵累积标准差的有效计算
【发布时间】:2011-02-15 11:03:35
【问题描述】:

我最近在 r-help 邮件列表上发布了这个问题,但没有得到任何答案,所以我想我也将它发布在这里,看看是否有任何建议。

我正在尝试计算矩阵的累积标准差。我想要一个接受矩阵并返回相同大小的矩阵的函数,其中输出单元格 (i,j) 设置为第 1 行和第 i 行之间输入列 j 的标准偏差。 NAs 应该被忽略,除非输入矩阵的单元格 (i,j) 本身是 NA,在这种情况下输出矩阵的单元格 (i,j) 也应该是 NA。

我找不到内置函数,所以我实现了以下代码。不幸的是,这使用了一个循环,最终对于大型矩阵来说有点慢。是否有更快的内置函数或有人可以提出更好的方法?

cumsd <- function(mat)
{
    retval <- mat*NA
    for (i in 2:nrow(mat)) retval[i,] <- sd(mat[1:i,], na.rm=T)
    retval[is.na(mat)] <- NA
    retval
}

谢谢。

【问题讨论】:

    标签: r statistics


    【解决方案1】:

    您可以使用cumsum 来计算从方差/标准差的直接公式到矩阵矢量化运算的必要总和:

    cumsd_mod <- function(mat) {
        cum_var <- function(x) {
            ind_na <- !is.na(x)
            nn <- cumsum(ind_na)
            x[!ind_na] <- 0
            cumsum(x^2) / (nn-1) - (cumsum(x))^2/(nn-1)/nn
        }
        v <- sqrt(apply(mat,2,cum_var))
        v[is.na(mat) | is.infinite(v)] <- NA
        v
    }
    

    只是为了比较:

    set.seed(2765374)
    X <- matrix(rnorm(1000),100,10)
    X[cbind(1:10,1:10)] <- NA # to have some NA's
    
    all.equal(cumsd(X),cumsd_mod(X))
    # [1] TRUE
    

    关于时间安排:

    X <- matrix(rnorm(100000),1000,100)
    system.time(cumsd(X))
    # user  system elapsed 
    # 7.94    0.00    7.97 
    system.time(cumsd_mod(X))
    # user  system elapsed 
    # 0.03    0.00    0.03 
    

    【讨论】:

    • 非常好的 Marek,这让我的分析更有效率。仅供参考,您似乎没有在函数中使用变量 n
    • 这是早期版本之一的残留物;)。
    • 小心使用这个算法; @Marek 有一个好主意,但是当 sd 相对于均值较小时,使用此等式计算方差会产生有趣的结果。维基百科有better algorithms;另见我的回答here
    • @Aaron 这是非常好的观点。在空闲时间我会更新我的答案。谢谢
    【解决方案2】:

    再试一次(Marek 的更快)

    cumsd2 <- function(y) {
    n <- nrow(y)
    apply(y,2,function(i) {
        Xmeans <- lapply(1:n,function(z) rep(sum(i[1:z])/z,z))
        Xs <- sapply(1:n, function(z) i[1:z])
        sapply(2:n,function(z) sqrt(sum((Xs[[z]]-Xmeans[[z]])^2,na.rm = T)/(z-1)))
    })
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-23
      • 1970-01-01
      • 2019-02-15
      相关资源
      最近更新 更多