2013-07-23 6 views
9

ich mit NAs einen Datenrahmen haben und ich möchte die nationalen Agenturen mit der Zeile ersetzen, bedeutetSuchen und Ersetzen von fehlenden Werte mit der Zeile bedeuten

c1 = c(1,2,3,NA) 
c2 = c(3,1,NA,3) 
c3 = c(2,1,3,1) 

df = data.frame(c1,c2,c3) 

> df 
    c1 c2 c3 
1 1 3 2 
2 2 1 1 
3 3 NA 3 
4 NA 3 1 

dass so

> df 
    c1 c2 c3 
1 1 3 2 
2 2 1 1 
3 3 3 3 
4 2 3 1 

Antwort

10

Sehr ähnlich @ Baptistes Antwort

> ind <- which(is.na(df), arr.ind=TRUE) 
> df[ind] <- rowMeans(df, na.rm = TRUE)[ind[,1]] 
+1

+1 gute Verwendung des oft übersehenen 'arr.ind' -Arguments –

+0

Ich habe festgestellt, dass wenn ich ganze Zeilen von NAs habe, ein Fehler auftritt. Ist es richtige Etikette, dies als eine ganz neue Frage zu stellen? – Brian

2

Meine Lösung ist

rwmns = rowMeans(df,na.rm=TRUE) 
df$c1[is.na(df$c1)] = rwmns[is.na(df$c1)] 
df$c2[is.na(df$c2)] = rwmns[is.na(df$c2)] 
df$c3[is.na(df$c3)] = rwmns[is.na(df$c3)] 
> df 
    c1 c2 c3 
1 1 3 2 
2 2 1 1 
3 3 3 3 
4 2 3 1 

Gibt es einen eleganteren Weg, besonders wenn jemand viele Spalten hat?

+4

Große Arbeit kommt zur Umsetzung. Sie können '[] verwenden, um zu indizieren, so dass jede Zeile zu 'df [[col_name]] wird [is.na (df [[col_name]])] <- rwmns [is.na (df [[col_name]]) '. Auf diese Weise können Sie eine Anwendungsfamilie über die Spaltennamen schleifen oder verwenden, für die Sie eine Ersetzung durchführen möchten. – Justin

4

Ich denke, das funktioniert,

df[which(is.na(df), arr.ind=TRUE)] <- rowMeans(df[!complete.cases(df), ], na.rm=TRUE) 
+0

+1 nette Lösung !! Viel besser als mein faules 'apply'! –

+0

es ist ein wenig überflüssig, sowohl is.na und complete.cases zu verwenden; es gibt wahrscheinlich mehr einen effizienteren Weg in zwei Zeilen – baptiste

+1

So vielleicht? 'idx <- was (is.na (df), arr.ind = TRUE); df [idx] <- rowMeans (df [idx [, 1],], na.rm = WAHR) ' –

3

Mit apply (man beachte das zurückgegebene Objekt ist ein matrix):

t(apply(df , 1 , function(x) { x[ is.na(x) ] = mean(x , na.rm = TRUE); x })) 
    c1 c2 c3 
[1,] 1 3 2 
[2,] 2 1 1 
[3,] 3 3 3 
[4,] 2 3 1 

Wir verwenden irgendeine anonyme Funktion die Werte der einzelnen NA in jeder Zeile zu ändern an die mean dieser Reihe. Der einzige Vorteil ist, dass Sie nicht mehr tippen müssen, wenn die Anzahl der Zeilen zunimmt. Es ist nicht besonders effizient oder schnell in einem rechnerischen Sinne, aber mehr in einem kognitiven Sinne (Sie werden es nicht bemerken, es sei denn, Sie haben 000,000 Reihen).

2

Eine weitere Option ist na.aggregate von library(zoo) nach dem Datensatz mit Ihrer eigenen Lösung

library(zoo) 
df[] <- t(na.aggregate(t(df))) 
df 
# c1 c2 c3 
#1 1 3 2 
#2 2 1 1 
#3 3 3 3 
#4 2 3 1