2016-08-08 32 views
6

Widziałem rozwiązanie tego problemu, ale nie mogę go uruchomić dla grup (Fill NA in a time series only to a limited number) i uważam, że musi być lepszy sposób to zrobić?na.locf Wypełniaj maksymalnie do maxgap, nawet jeśli gap> maxgap, z grupami

Say mam następujący 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 

Co chciałbym zrobić, to wypełnić NA s zarówno do przodu i do tyłu od ostatniej wartości nie- NA, ale tylko do pewnego maksymalnie dwa rzędy do przodu lub do tyłu.

Też potrzebuję tego zrobić przez grupę (ID).

Próbowałem, używając na.locf/na.approx z maxgap = x etc, ale nie wypełnia NA S, jeżeli przerwa między nie- NA wartości jest większa niż maxgap. Podczas gdy chcę wypełnić te dane do przodu i do tyłu, nawet jeśli różnica między wartościami innymi niż NA jest większa niż maxgap, ale tylko przez dwa wiersze.

Efekt końcowy powinien wyglądać mniej więcej tak:

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 

W rzeczywistości, mój zestaw danych jest ogromna, a ja chcę być w stanie wypełnić NA s przodu i do tyłu dla maksymalnie 672 wierszy, ale nie więcej , według grupy.

Dzięki!

Odpowiedz

4

Na przykład pokazał, że grupa przez „ID”, uzyskać shift z „Cena” z n = 0:2 i type jako „ołów”, aby utworzyć 3 kolumny tymczasowe, uzyskać pmax z tego, wykorzystać wyjście wykonać shift z type = 'lag' (domyślnie jest to „opóźnienie”) i sama n, uzyskać pmin i przypisać ją jako

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 

bardziej ogólne podejście „Price_Fill” byłoby zrobić pmin/pmax na .I, ponieważ "Cena" może się różnić, a nie numer kolejny, jak pokazano w poście PO.

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 

czyli załóżmy, że zmiany 'cena', to będzie inna

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

Zapisano mnie znowu @akrun. Dzięki! – LyssBucks