na.locf填充NAs到maxgap即使gap> maxgap,也有组

Lys*_*cks 7 r na data.table

我已经看到了解决这个问题的方法,但无法让它适用于群组(在时间序列中只填充有限数量的NA),并且认为必须有更简洁的方法来执行此操作?

说我有以下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
Run Code Online (Sandbox Code Playgroud)

我想这样做,是为了填补NA小号向前,并从最近的非回NA值,但只有最多两排向前或向后的.

我还需要它由小组(ID)来完成.

我已经尝试过使用na.locf/ na.approxwith maxgap = x等,但它没有填充NANA值之间的差距大于的地方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
Run Code Online (Sandbox Code Playgroud)

实际上,我的数据集是庞大的,我希望能够NA向前和向后填充最多672行,但不能再按组进行填充.

谢谢!

akr*_*run 5

对于示例显示,我们按'ID'分组,得到shift'Price' n = 0:2,并type作为'lead'创建3个临时列,从中获取pmax,使用输出来执行shiftwith type = 'lag'(默认情况下是'滞后' ')同样n,得到pmin并将其指定为'Price_Fill'

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
Run Code Online (Sandbox Code Playgroud)

更一般的方法是进行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
Run Code Online (Sandbox Code Playgroud)

即假设我们改变'价格',它将是不同的

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
Run Code Online (Sandbox Code Playgroud)