2016-08-08 13 views
6

Я видел решение этого, но не могу заставить его работать для групп (Fill NA in a time series only to a limited number) и думал, что там должно быть аккуратно способ сделать это также?na.locf заполнить NAs до maxgap, даже если зазор> maxgap, с группами

Скажем, у меня есть следующий 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 

То, что я хотел бы сделать, это заполнить NA s как вперед и назад от последнего значения не- NA, но только до максимум две строки вперед или назад.

Мне также нужно, чтобы это выполнялось группой (ID).

Я попытался с помощью na.locf/na.approx с maxgap = x и т.д., но не заполняет NA S, где разрыв между не- NA значений больше, чем maxgap. В то время как я хочу заполнить их вперед и назад, даже если зазор между значениями не NA больше, чем maxgap, но только двумя строками.

Конечный результат должен выглядеть примерно так:

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 

В действительности, мой набор данных не является массовым, и я хочу, чтобы иметь возможность заполнить NA S вперед и назад до 672 строк, но не более , по группам.

Спасибо!

ответ

4

Для примера показал, мы группа по «ID», получить shift из «Цена» с n = 0:2 и type как «свинец», чтобы создать 3 временные столбцы, получить pmax от этого, использовать выход сделать shift с type = 'lag' (по умолчанию это «лаг») и то же самое n, получить pmin и назначить его в качестве

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 

более общий подход «Price_Fill» должен был бы сделать pmin/pmax на .I, так как «Цена» может быть разной, а не порядковым номером, как показано в сообщении OP.

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 

т.е. предположим, что мы изменить 'Цена', она будет отличаться

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

Сохраненный меня снова @akrun. Благодаря! – LyssBucks

 Смежные вопросы

  • Нет связанных вопросов^_^