【问题标题】:Omit inf from row sum in R从R中的行总和中省略inf
【发布时间】:2013-03-13 18:12:42
【问题描述】:

所以我试图对矩阵的行求和,其中有 inf。如何对行求和,省略 inf?

【问题讨论】:

  • 我很震惊没有人问过传统的 StackOverflow 问题:“你试过什么?”
  • 我对 +9 感到震惊(到目前为止)。 Upvote 明确指出 这个问题显示了研究工作

标签: r rowsum


【解决方案1】:

将您的矩阵乘以is.finite(m) 的结果,然后在具有na.rm=TRUE 的乘积上调用rowSums。这是因为Inf*0NaN

m <- matrix(c(1:3,Inf,4,Inf,5:6),4,2)
rowSums(m*is.finite(m),na.rm=TRUE)

【讨论】:

    【解决方案2】:
    A[is.infinite(A)]<-NA
    rowSums(A,na.rm=TRUE)
    

    一些基准比较:

    library(microbenchmark)
    
    
    rowSumsMethod<-function(A){
     A[is.infinite(A)]<-NA
     rowSums(A,na.rm=TRUE)
    }
    applyMethod<-function(A){
     apply( A , 1 , function(x){ sum(x[!is.infinite(x)])})
    }
    
    rowSumsMethod2<-function(m){
      rowSums(m*is.finite(m),na.rm=TRUE) 
    }
    
    rowSumsMethod0<-function(A){
     A[is.infinite(A)]<-0
     rowSums(A)
    }
    
    A1 <- matrix(sample(c(1:5, Inf), 50, TRUE), ncol=5)
    A2 <- matrix(sample(c(1:5, Inf), 5000, TRUE), ncol=5)
    microbenchmark(rowSumsMethod(A1),rowSumsMethod(A2),
                   rowSumsMethod0(A1),rowSumsMethod0(A2),
                   rowSumsMethod2(A1),rowSumsMethod2(A2),
                   applyMethod(A1),applyMethod(A2))
    
    Unit: microseconds
                   expr      min        lq    median        uq      max neval
      rowSumsMethod(A1)   13.063   14.9285   16.7950   19.3605 1198.450   100
      rowSumsMethod(A2)  212.726  220.8905  226.7220  240.7165  307.427   100
     rowSumsMethod0(A1)   11.663   13.9960   15.3950   18.1940  112.894   100
     rowSumsMethod0(A2)  103.098  109.6290  114.0610  122.9240  159.545   100
     rowSumsMethod2(A1)    8.864   11.6630   12.5960   14.6955   49.450   100
     rowSumsMethod2(A2)   57.380   60.1790   63.4450   67.4100   81.172   100
        applyMethod(A1)   78.839   84.4380   92.1355   99.8330  181.005   100
        applyMethod(A2) 3996.543 4221.8645 4338.0235 4552.3825 6124.735   100
    

    所以约书亚的方法赢了!而且 apply 方法显然比其他两种方法慢(当然相对而言)。

    【讨论】:

    • 你可以和!is.infinite()合二为一!
    • 所以我会使用sums &lt;- apply( A , 1 , FUN = function(x){ sum(x[!is.infinite(x)])})
    • 你知道测量单位是百万分之一秒吧?!但是,是的,对于较大的矩阵,NA 子集化要快 0.004 秒! :-)
    • 是的,当然差异很小,我认为没有任何有意义的差异,基准测试很有趣:)
    • 如果你要替换矩阵中的值,你可以用0替换并留下na.rm=FALSE,这样可能会更快。
    【解决方案3】:

    我会使用 applyis.infinite 以避免将 Inf 值替换为 @Hemmo 的答案中的 NA

    > set.seed(1)
    > Mat <- matrix(sample(c(1:5, Inf), 50, TRUE), ncol=5)
    > Mat # this is an example
          [,1] [,2] [,3] [,4] [,5]
     [1,]    2    2  Inf    3    5
     [2,]    3    2    2    4    4
     [3,]    4    5    4    3    5
     [4,]  Inf    3    1    2    4
     [5,]    2    5    2    5    4
     [6,]  Inf    3    3    5    5
     [7,]  Inf    5    1    5    1
     [8,]    4  Inf    3    1    3
     [9,]    4    3  Inf    5    5
    [10,]    1    5    3    3    5
    > apply(Mat, 1, function(x) sum(x[!is.infinite(x)]))
     [1] 12 15 21 10 18 16 12 11 17 17
    

    【讨论】:

    • 我们似乎发布了完全相同的方法!
    • 我提供了全方位的 +1,再次阐明了做同样事情的许多方法,并让我思考做简单事情的 最佳 方法。我喜欢约书亚的把戏。
    【解决方案4】:

    试试这个...

    m <- c( 1 ,2 , 3 , Inf , 4 , Inf ,5 )
    sum(m[!is.infinite(m)])
    

    或者

    m <- matrix( sample( c(1:10 , Inf) , 100 , rep = TRUE ) , nrow = 10 )
    sums <- apply( m , 1 , FUN = function(x){ sum(x[!is.infinite(x)])})
    
    > m
          [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
     [1,]    8    9    7  Inf    9    2    2    6    1   Inf
     [2,]    8    7    4    5    9    5    8    4    7    10
     [3,]    7    9    3    4    7    3    3    6    9     4
     [4,]    7  Inf    2    6    4    8    3    1    9     9
     [5,]    4  Inf    7    5    9    5    3    5    9     9
     [6,]    7    3    7  Inf    7    3    7    3    7     1
     [7,]    5    7    2    1  Inf    1    9    8    1     5
     [8,]    4  Inf   10  Inf    8   10    4    9    7     2
     [9,]   10    7    9    7    2  Inf    4  Inf    4     6
    [10,]    9    4    6    3    9    6    6    5    1     8
    
    > sums
     [1] 44 67 55 49 56 45 39 54 49 57
    

    【讨论】:

      【解决方案5】:

      这是一种“非应用”且非破坏性的方法:

      rowSums( matrix(match(A, A[is.finite(A)]), nrow(A)), na.rm=TRUE)
      [1] 2 4
      

      虽然效率相当高,但不如 Johsua 的乘法方法快。

      【讨论】:

      • 好吧,我想你的意思是match(A, A[is.finite(A)])。我已经编辑过了。希望你不要介意。
      • 那不是在我的会话中工作的代码。似乎 ti 的效率会降低。
      • 你的意思是我的编辑不是你的代码?我用A[is.finite(A)] 替换了is.finite(A)。没有这个,match 会吐出所有的 NA,因为它匹配所有值为 TRUE 的值。因此,只有值 1 将与 TRUE 匹配。其他所有值都将获得 NA。
      • 我猜我的测试用例有不同的结果,但它只是一个 2 x 2 矩阵。
      猜你喜欢
      • 2012-07-04
      • 2019-11-10
      • 2019-06-28
      • 1970-01-01
      • 2022-01-18
      • 2012-04-12
      • 2021-12-07
      • 2011-08-02
      • 2019-02-14
      相关资源
      最近更新 更多