2016-08-08 47 views
6

Ich habe eine Lösung für dieses gesehen, kann aber nicht für Gruppen (Fill NA in a time series only to a limited number) arbeiten, und dachte, es muss ein besserer sein Möglichkeit, dies auch zu tun?na.locf fill NAs bis maxgap auch wenn gap> maxgap, mit Gruppen

Sagen wir, ich habe folgendes dt:

dt <- data.table(ID = c(rep("A", 10), rep("B", 10)), Price = c(seq(1, 10, 1), seq(11, 20, 1))) 
dt[c(1:2, 5:10), 2] <- NA 
dt[c(11:13, 15:19) ,2] <- NA 
dt 
    ID Price 
1: A NA 
2: A NA 
3: A  3 
4: A  4 
5: A NA 
6: A NA 
7: A NA 
8: A NA 
9: A NA 
10: A NA 
11: B NA 
12: B NA 
13: B NA 
14: B 14 
15: B NA 
16: B NA 
17: B NA 
18: B NA 
19: B NA 
20: B 20 

Was ich tun möchte, ist NA s beide nach vorne und aus der letzten nicht NA Wert zurück zu füllen, sondern nur auf eine nach oben maximal zwei Reihen vor oder zurück.

Ich brauche es auch von der Gruppe (ID) getan werden.

Ich habe versucht, na.locf/na.approx mit maxgap = x usw. verwenden, aber es füllt nicht NA s, wo die Lücke zwischen nicht NA Werten größer als maxgap ist. Hingegen möchte ich diese vorwärts und rückwärts füllen, auch wenn der Abstand zwischen den Werten größer als maxgap ist, aber nur zwei Zeilen.

Das Endergebnis sollte in etwa so aussieht:

ID Price Price_Fill 
1: A NA   3 
2: A NA   3 
3: A  3   3 
4: A  4   4 
5: A NA   4 
6: A NA   4 
7: A NA   NA 
8: A NA   NA 
9: A NA   NA 
10: A NA   NA 
11: B NA   NA 
12: B NA   14 
13: B NA   14 
14: B 14   14 
15: B NA   14 
16: B NA   14 
17: B NA   NA 
18: B NA   20 
19: B NA   20 
20: B 20   20 

In Wirklichkeit mein Datensatz ist massiv, und ich möchte in der Lage sein zu füllen NA s vorwärts und zurück für bis zu 672 Zeilen, aber nicht mehr , nach Gruppe.

Danke!

Antwort

4

Für das Beispiel gezeigt, wir Gruppe von ‚ID‘, die shift von ‚Preis‘ erhalten mit n = 0:2 und type als ‚führen‘ 3 temporäre Spalten zu erstellen, erhalten die pmax daraus, verwenden Sie die Ausgabe der zu tun shift mit type = 'lag' (standardmäßig ist es lag ') erhalten die pmin und gleiche n und weisen sie als

dt[, Price_Fill := do.call(pmin, c(shift(do.call(pmax, c(shift(Price, n = 0:2, 
        type = "lead"), na.rm=TRUE)), n= 0:2), na.rm = TRUE)) , by = ID] 
dt 
# ID Price Price_Fill 
#1: A NA   3 
#2: A NA   3 
#3: A  3   3 
#4: A  4   4 
#5: A NA   4 
#6: A NA   4 
#7: A NA   NA 
#8: A NA   NA 
#9: A NA   NA 
#10: A NA   NA 
#11: B NA   NA 
#12: B NA   14 
#13: B NA   14 
#14: B 14   14 
#15: B NA   14 
#16: B NA   14 
#17: B NA   NA 
#18: B NA   20 
#19: B NA   20 
#20: B 20   20 

Ein allgemeinerer Ansatz der pmin/pmax wäre ‚Price_Fill‘ aufzu tunals "Preis" kann unterschiedlich sein und nicht die Sequenznummer, wie sie im OP-Beitrag angezeigt wird.

i1 <- dt[, do.call(pmin, c(shift(do.call(pmax, c(shift(NA^(is.na(Price))* 
    .I, n = 0:2, type = "lead"), na.rm = TRUE)), n = 0:2), na.rm = TRUE)), ID]$V1 

dt$Price_Fill < dt$Price[i1] 
dt$Price_Fill 
#[1] 3 3 3 4 4 4 NA NA NA NA NA 14 14 14 14 14 NA 20 20 20 

d nehmen wir den 'Preis' zu ändern, wird es anders

dt$Price[3] <- 10 
dt$Price[14] <- 7 
dt$Price_Fill <- dt$Price[i1] 
dt$Price_Fill 
#[1] 10 10 10 4 4 4 NA NA NA NA NA 7 7 7 7 7 NA 20 20 20 
+1

wieder gespeichert mich @akrun. Vielen Dank! – LyssBucks