2016-04-11 4 views
1

Ich summiere über mehrere Spalten, einige, die NA haben. Ich verwendeIgnorieren NA beim Summieren mehrerer Spalten mit dplyr

dplyr::mutate 

und dann schreiben die arithmetische Summe der Spalten, um die Summe zu erhalten. Aber die Spalten haben NA und ich möchte sie als Null behandeln. Ich konnte es mit rowSums (siehe unten), aber jetzt mit muate arbeiten. Die Verwendung von muate macht es lesbarer, erlaubt mir aber auch, Spalten zu subtrahieren. Das Beispiel ist unten.

Wie stelle ich sicher, dass NA in Petal.Length im obigen Ausdruck als Null behandelt wird? Ich weiß mit rowSums ich so etwas tun können:

iris$sum <- rowSums(DF[,c("Sepal.Length","Petal.Length")], na.rm = T) 

aber mit mutieren ist es einfacher zu setzen sogar diff = Sepal.Length - Petal.Length. Was wäre ein vorgeschlagener Weg, dies mit Mutate zu erreichen?

Hinweis der Post ist ähnlich

http://stackoverflow.com/questions/28873057/sum-across-multiple-columns-with-dplyr 
http://stackoverflow.com/questions/23255318/subtract-multiple-columns-ignoring-na 

Antwort

2

Das Problem mit Ihrem rowSums ist der Verweis auf DF (die nicht definiert ist). Dies funktioniert:

mutate(iris, sum2 = rowSums(cbind(Sepal.Length, Petal.Length), na.rm = T)) 

Für Unterschied, können Sie natürlich eine negative verwenden: rowSums(cbind(Sepal.Length, -Petal.Length), na.rm = T)

Die allgemeine Lösung ist ifelse oder ähnliches zu verwenden, um die fehlenden Werte auf 0 (oder was auch immer ist angemessen) zu setzen:

mutate(iris, sum2 = Sepal.Length + ifelse(is.na(Petal.Length), 0, Petal.Length)) 

effizienter als ifelse wäre eine Implementierung von coalesce sein, see examples here. Dies verwendet die @ krlmlr-Antwort vom vorherigen Link (siehe unten für den Code oder kimisc package).

mutate(iris, sum2 = Sepal.Length + coalesce.na(Petal.Length, 0)) 

Um fehlende Werte Datensatz breit zu ersetzen, da replace_na im tidyr Paket.


@ krlmlr der coalesce.na, as found here

coalesce.na <- function(x, ...) { 
    x.len <- length(x) 
    ly <- list(...) 
    for (y in ly) { 
    y.len <- length(y) 
    if (y.len == 1) { 
     x[is.na(x)] <- y 
    } else { 
     if (x.len %% y.len != 0) 
     warning('object length is not a multiple of first object length') 
     pos <- which(is.na(x)) 
     x[pos] <- y[(pos - 1) %% y.len + 1] 
    } 
    } 
    x 
}