2016-05-06 4 views
-2

Ich habe ein Datenframe mit wenigen Reihen von identischen Zeilennamen. Ich möchte NAs jeder zweiten Zeile durch die nicht-NA der identischen unmittelbaren vorherigen Zeile ersetzen. Wenn jedoch bereits ein Wert in der zweiten Zeile existiert, sollte dies nicht beeinflusst werden.Geändert: Ersetzen von Werten von Zeilen mit identischen Rownames in einem Datenrahmen

Bitte siehe unten:

df:

date    1 1 2 3 3 

20040101  100 150 NA NA 140 

20040115  200 NA 200 NA NA 

20040131  170 NA NA NA NA 
20040131  NA 165 180 190 190 

20040205  NA NA NA NA NA 

20040228  140 145 165 150 155 
20040228  NA NA NA NA NA 

20040301  150 155 170 150 160 

20040315  NA NA 180 190 200 

20040331  NA 145 160 NA NA 
20040331  NA NA NA 175 180 

ich die resultierende Datenrahmen sein wollen:

df_new:

date  1 1 2 3 3 

20040101  100 150 NA NA 140 

20040115  200 NA 200 NA NA 

20040131  170 165 180 190 190 

20040205  NA NA NA NA NA 

20040228  140 145 165 150 155 

20040301  150 155 170 150 160 

20040315  NA NA 180 190 200 

20040331  NA 145 160 175 180 

ich versucht habe, die folgende for-Schleife , aber die Ergebnisse sind nicht wie gewünscht:

for (i in 2: nrow (df)) {

if(all(is.na(df[i, ]))){ df[i, ] = fill[(i-1), ]} 

out [i,] < - df [i-1, ncol] }

Bitte leitet mich in dieser Hinsicht.

Dank Saba

+0

Was sollte ich hinzufügen, um es schönes Format zu machen? –

+0

Fügen Sie Beispiele Ihrer Daten mit 'dput()' in Ihre Frage ein. Um beispielsweise zehn Zeilen von df1 bereitzustellen, fügen Sie in die Ausgabe von 'dput (df1 [1:10,])' 'ein. Dadurch können Personen Ihre Daten einfach in ihre R-Konsole kopieren und einfügen. – eipi10

+0

@ ZheyuanLi: Es ist nicht streng der Fall, wo für alle NAs von DF1 eine Nicht-NA von DF2 ist. In den meisten Fällen haben sowohl df1 als auch df2 NAs in identischen Reihen. Aber ich möchte nur diejenigen NAs von df1 ersetzen, die parallele Nicht-NAs von df2 verfügbar haben. –

Antwort

2

Hier ist eine Option mit data.table. Wir platzieren die Datensätze in einem list, dann machen es eine einzige data.table mit rbindlist, nach "date" gruppiert, durchlaufen die Spalten (lapply(.SD, ..) und Subset die Nicht-NA-Elemente.

library(data.table) 
unique(rbindlist(list(df1, df2))[,lapply(.SD, function(x) 
     if(all(is.na(x))) x else x[!is.na(x)]) , date]) 
#  date X11A X11A.1 X21B X3CC X3CC.1 
#1: 20040101 100 150 NA NA 140 
#2: 20040115 200  NA 200 NA  NA 
#3: 20040131 170 165 180 190 190 
#4: 20040205 NA  NA NA NA  NA 
#5: 20040228 140 145 165 150 155 
#6: 20040301 150 155 170 150 160 
#7: 20040315 NA  NA 180 190 200 
#8: 20040331 NA 145 160 175 180 

Als OP merkt über die Verwendung von for Schleife und which, eine weitere Option mit data.table die mit set beide verwendet

setDT(df1) 
dfN <- setDT(df2)[df1, on = "date"] 
for(j in 2:ncol(df1)){ 
    set(df1, i = which(is.na(df1[[j]])), j = j, 
        value = dfN[[j]][is.na(df1[[j]])]) 
} 
df1 
#  date X11A X11A.1 X21B X3CC X3CC.1 
#1: 20040101 100 150 NA NA 140 
#2: 20040115 200  NA 200 NA  NA 
#3: 20040131 170 165 180 190 190 
#4: 20040205 NA  NA NA NA  NA 
#5: 20040228 140 145 165 150 155 
#6: 20040301 150 155 170 150 160 
#7: 20040315 NA  NA 180 190 200 
#8: 20040331 NA 145 160 175 180 
0

Eine alternative Lösung unter Verwendung von data.table wäre:

library(data.table) 

setDT(df) 

df[,lapply(.SD,mean,na.rm=T),by=date] 

## date X11A X11A.1 X21B X3CC X3CC.1 
##1: 20040101 100 150 NaN NaN 140 
##2: 20040115 200 NaN 200 NaN NaN 
##3: 20040131 170 165 180 190 190 
##4: 20040205 NaN NaN NaN NaN NaN 
##5: 20040228 140 145 165 150 155 
##6: 20040301 150 155 170 150 160 
##7: 20040315 NaN NaN 180 190 200 
##8: 20040331 NaN 145 160 175 180 

Annahme: Hier gehe ich davon aus, dass für den Fall, dass zahlreiche Tupel für ein einzelnes Datum auftreten, jede Spalte nur einen eindeutigen Wert hat, ansonsten NA.

Verwandte Themen