从R中的行和中省略inf

时间:2013-03-13 18:12:42

标签: r rowsum

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

5 个答案:

答案 0 :(得分:31)

将您的矩阵乘以is.finite(m)的结果,并使用rowSums在产品上调用na.rm=TRUE。这是有效的,因为Inf*0NaN

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

答案 1 :(得分:19)

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方法明显慢于其他两种方法(当然相对而言)。

答案 2 :(得分:11)

我会使用applyis.infinite,以避免将Inf值替换为NA,就像@Hemmo的回答一样。

> 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

答案 3 :(得分:8)

试试这个......

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

答案 4 :(得分:3)

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

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

尽管效率相当高,但它并不像Johsua的乘法方法那么快。