【问题标题】:for loop to sum values in a vector by groups of two in Rfor循环按R中的两个组对向量中的值求和
【发布时间】:2021-08-27 12:22:30
【问题描述】:

假设我有以下代码

u <- c(1,2,3,4,5,6)
l <- c()
for (i in j) {
  l[i] <- u[i]+u[i+1]
}

我想创建一个 for 循环,以便获得以下三个值:u[1]+u[2] 和 u[3]+u[4],最后是 u[5]+u[6 ].

【问题讨论】:

    标签: r for-loop vector


    【解决方案1】:

    不需要for循环,你可以这样做:

    tapply(u, ceiling(seq_along(u)/2), sum)
    
     1  2  3 
     3  7 11 
    

    【讨论】:

    • 感谢您提供此信息。我从来没有遇到过这个tapply功能。这对我很有用。
    【解决方案2】:
    for (i in 1:length(u)) {
      if(i %% 2 ==0){
        print(u[i] + u[i-1])
      }
    }
    

    i %% 2 == 0 表示 i 是偶数。

    结果

    [1] 3
    [1] 7
    [1] 11
    

    【讨论】:

    • 谢谢,这也是一个完美的解决方案!
    【解决方案3】:

    我建议如下,因为它很生动: 通过2 创建一个length(u) 矩阵并对行求和

    rowSums(matrix(u, ncol = 2, byrow = TRUE))
    

    这也应该是一个非常快速的解决方案,因为您可以在R 中使用大规模矢量化。例如

    u <- c(1,2,3,4,5,6)
    microbenchmark::microbenchmark(rowSums(matrix(u,ncol=2,byrow = TRUE)),
                                   tapply(u, ceiling(seq_along(u)/2), sum))
    

    在我的机器上提供以下基准:

    Unit: microseconds
                                           expr  min    lq   mean median   uq   max neval
     rowSums(matrix(u, ncol = 2, byrow = TRUE))  4.3  4.80  6.920   6.50  7.3  27.1   100
        tapply(u, ceiling(seq_along(u)/2), sum) 77.5 83.45 89.378  85.25 87.8 206.4   100
    

    u 扩展到10000 个元素,tapply-解决方案变得非常慢,请参阅

    u <- rnorm(1:1e4)
    microbenchmark::microbenchmark(rowSums(matrix(u,ncol=2,byrow = TRUE)),
                                   tapply(u, ceiling(seq_along(u)/2), sum))
    
    Unit: microseconds
                                           expr     min       lq      mean   median       uq     max neval
     rowSums(matrix(u, ncol = 2, byrow = TRUE))    49.1    57.45    71.145    67.25    73.50   166.4   100
        tapply(u, ceiling(seq_along(u)/2), sum) 17995.5 19488.75 20653.714 20388.00 21223.55 34126.6   100
    

    更新:您甚至可以使用colSums(matrix(u, nrow = 2)) 挤出更多内容,因为这样您就可以在R 中使用默认的byrow=FALSE-matrix-construction(也会减少代码):

    u <- 1:1e5
    microbenchmark::microbenchmark(rowSums(matrix(u, ncol = 2, byrow = TRUE)),
                                   colSums(matrix(u, nrow = 2)))
    
    
    Unit: microseconds
                                           expr   min     lq    mean median     uq    max neval
     rowSums(matrix(u, ncol = 2, byrow = TRUE)) 767.5 812.65 916.154 851.95 948.25 1669.4   100
                   colSums(matrix(u, nrow = 2)) 217.0 232.90 263.355 240.00 272.45  469.8   100
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-20
      • 1970-01-01
      • 2021-09-15
      • 1970-01-01
      相关资源
      最近更新 更多