2017-10-13 1 views
-2

Sagen, ich habe eine data.frame:ersetzen NA mit durchschnittlich Fall vor und nach der NA, es sei denn, Zeile beginnt oder endet mit NA

t<-c(1,1,2,4,NA,3) 
u<-c(1,3,4,6,4,2) 
v<-c(2,3,4,NA,3,2) 
w<-c(2,3,4,5,2,3) 
x<-c(2,3,4,5,6,NA) 
df<-data.frame(t,u,v,w,x) 
df 

    t u v w x 
1 1 1 2 2 2 
2 1 3 3 3 3 
3 2 4 4 4 4 
4 4 6 NA 5 5 
5 NA 4 3 2 6 
6 3 2 2 3 NA 

Ich möchte die nationalen Agenturen ändern, so dass die NA wird ersetzt durch den Durchschnitt des einen Wertes vor dem NA und des einen Wertes nach dem NA. Wenn eine Zeile jedoch mit einer NA beginnt, möchte ich, dass sie durch den folgenden Wert ersetzt wird. Wenn eine Zeile mit NA endet, möchte ich, dass sie durch den Wert vor der NA ersetzt wird. So würde ich gerne folgendes Ergebnis erhalten:

t u v w x 
1 1 1 2 2 2 
2 1 3 3 3 3 
3 2 4 4 4 4 
4 4 6 5.5 5 5 --> NA becomes average of 6 and 5 
5 4 4 3 2 6 --> NA becomes value of next case 
6 3 2 2 3 3 --> NA becomes value of previous case 

Ich habe Tausende von Zeilen, so dass jede Hilfe sehr geschätzt wird!

Antwort

0

Basierend auf früheren na.approx Lösungen könnte dies den Trick:

library(zoo) 
t(apply(df, 1,function(x) na.approx(x,rule=2))) 
+0

Dies hat tatsächlich den Trick gemacht! Du bist ein wahrer Held. –

+0

Ich bekomme diesen Fehler 'Fehler in na.approx (x, Regel = 2): konnte Funktion" na.approx "' –

+1

'Bibliothek (Zoo)' bitte nicht finden. Enthalten Sie das – Sotos

0

Suchen Sie immer nach Parameter na.rm = T in Funktionen, die Sie verwenden. In diesem Fall möchten Sie den Mittelwert einer der Spalten mit dem Parameter na.rm als wahr verwenden. Dann möchten Sie NA-s ersetzen.

dt[is.na(dt[,'t']),'t'] = 0 

(unter der Annahme, dass ich nicht die Reihenfolge der Dimensionen umgekehrt hat)

0

Hier ist eine mögliche Lösung,

wenn NA mit (Verzögerung + Blei) ersetzen/2, wenn noch mit NA ersetzen Verzögerung, wenn immer noch NA durch Blei ersetzt wird.

library(dplyr) 
t(apply(df, 1, function(x){ 
    lagx = dplyr::lag(x) 
    leadx = dplyr::lead(x) 
    b = ifelse(is.na(x),(leadx+lagx)/2, x) 
    b = ifelse(is.na(b), leadx, b) 
    b = ifelse(is.na(b), lagx, b) 
    return(b) 
    } 
)) 
#output 
    t u v w x 
[1,] 1 1 2.0 2 2 
[2,] 1 3 3.0 3 3 
[3,] 2 4 4.0 4 4 
[4,] 4 6 5.5 5 5 
[5,] 4 4 3.0 2 6 
[6,] 3 2 2.0 3 3 
+0

Dies funktioniert auch! Vielen Dank!! –

+0

@Hardik gupta die Spalte ist nur auf eine Dezimalstelle gerundet, da ein imputierter Wert eine Dezimalzahl hat, dasselbe passiert, wenn Sie nur 'df [4,3] = 5.5' in den Startdaten haben. – missuse

0
t<-c(1,1,2,4,NA,3) 
u<-c(1,3,4,6,4,2) 
v<-c(2,3,4,NA,3,2) 
w<-c(2,3,4,5,2,3) 
x<-c(2,3,4,5,6,NA) 
df<-data.frame(t,u,v,w,x) 

df[which(is.na(t)), "t"] <- df[which(is.na(t)), "u"] 
df[which(is.na(x)), "x"] <- df[which(is.na(x)), "w"] 
df[which(is.na(v)), "v"] <- (df[which(is.na(v)), "u"] + df[which(is.na(v)), "w"])/2 

> df 
    t u v w x 
1 1 1 2.0 2 2 
2 1 3 3.0 3 3 
3 2 4 4.0 4 4 
4 4 6 5.5 5 5 
5 4 4 3.0 2 6 
6 3 2 2.0 3 3