2013-03-13 4 views
17

Also ich versuche, die Zeilen einer Matrix zu summieren, und es gibt infs drin. Wie summiere ich die Zeile und lasse die Infs weg?Lassen Sie inf aus der Zeilensumme in R

+1

Ich bin schockiert, dass niemand die traditionelle StackOverflow-Frage gestellt hat: "Was hast du probiert?" –

+10

Ich bin schockiert bei +9 (bisher). Upvote sagt eindeutig * Diese Frage zeigt den Forschungsaufwand * –

Antwort

8

Versuchen Sie, diese ...

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

Oder

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 
18
A[is.infinite(A)]<-NA 
rowSums(A,na.rm=TRUE) 

Einige Benchmarking zum Vergleich:

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 

So Joshua Methode gewinnt! Und anwenden Methode ist deutlich langsamer als zwei andere Methoden (relativ natürlich).

+0

Du kannst es in einem mit '! Is.infinite()'! –

+0

Also würde ich 'summen

+0

@ SimonO101 Das würde auch funktionieren, aber es ist etwas langsamer obwohl. –

11

I apply und is.infinite um verwenden würde Inf Werte von NA wie in @ Hemmo Antwort zu vermeiden, ersetzen.

> 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 
+0

Wir scheinen die exakt gleiche Methode gepostet zu haben! –

+0

@ SimonO101 du hast Recht wir haben den gleichen Beitrag. +1 für dich !!! –

+1

Ich gebe + 1's rundherum, um wieder viele Möglichkeiten zu beleuchten, dasselbe zu tun, und dafür, dass ich über den * besten * Weg nachdenke, etwas Einfaches zu tun. Ich mag Joshuas Trick. –

29

Multiplizieren Sie Ihre Matrix durch das Ergebnis der is.finite(m) und rowSums auf dem Produkt mit na.rm=TRUE nennen. Dies funktioniert, weil Inf*0NaN ist.

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

+1, schade, dass der beste Trick am wenigsten Stimmen hat :) –

3

Dies ist eine „Nicht-Anwendung“ und nicht-destruktiven Ansatz:

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

Obwohl es ziemlich effizient ist, ist es nicht so schnell wie Johsua der Multiplikationsverfahren ist.

+0

Okay, ich denke, du meintest 'match (A, A [is.finite (A)])'. Ich habe bearbeitet. Hoffe, es macht Ihnen nichts aus. – Arun

+0

Das war nicht der Code, der in meiner Sitzung funktionierte. Scheint so, als wäre es weniger effizient. –

+0

Sie meinen, meine Bearbeitung ist nicht Ihr Code? Ich habe "is.finite (A)" durch "A [is.finite (A)]" ersetzt. Ohne dies spuckt 'match' alle NAs aus, weil es allen Werten mit TRUE entspricht.Daher wird nur der Wert 1 mit TRUE verglichen. Jeder andere Wert wird NA erhalten. – Arun

Verwandte Themen