R数据表:使用shift()更新不按预期工作

3

我想使用shift将data.table列中的缺失值替换为下面的值,但是只有在我创建临时变量后才能使其生效。这是预期的行为吗?MWE:

library(data.table)

dt <- data.table(x=c(1, NA))
dt[is.na(x), x:=shift(x)]
# Fails

dt <- data.table(x=c(1, NA))
dt <- dt[, x.lag:=shift(x)]
dt[is.na(x), x:=x.lag]
# Works

当你在DT[i,j]中筛选i时,j只能用于子集。所以这是预期的行为。不过这是一个很好的例子。我希望看到更多的功能扩展,以更好地处理这种情况,比如DT[, x[is.na(x)] := shift(x)]或其他类似的方法。 - Frank
1个回答

3
我对data.table还不是很熟悉,但我认为rolling join可能是您在这里需要的。假设您想在有多个连续缺失值的情况下填充数据点,那么您的shift方法将只填充NA。
您的示例有些过于简洁,无法真正了解您的操作,但如果我将其扩展一些以包括一个记录列record,其中各种x值都缺失;
library(data.table)
dt <- data.table(record=1:10, x=c(1, NA, NA, 4, 5, 6, NA, NA, NA, 10))
> dt
    record  x
 1:      1  1
 2:      2 NA
 3:      3 NA
 4:      4  4
 5:      5  5
 6:      6  6
 7:      7 NA
 8:      8 NA
 9:      9 NA
10:     10 10

然后创建一个只包含非缺失行的副本,并将 x 列设置为关键字。

dtNA <- dt[!is.na(x)]
setkey(dtNA, record)
> dtNA
   record  x
1:      1  1
2:      4  4
3:      5  5
4:      6  6
5:     10 10

然后在完整的记录列表上进行滚动连接(如果某个值缺失,则向前滚动到先前的记录)。
dtNA[data.table(record=dt$record, key="record"), roll=TRUE]
    record  x
 1:      1  1
 2:      2  1
 3:      3  1
 4:      4  4
 5:      5  5
 6:      6  6
 7:      7  6
 8:      8  6
 9:      9  6
10:     10 10

与您的方法相比,其结果如下(仍然包含中的NA值);
dt[, x.lag:=shift(x)]
dt[is.na(x), x:=x.lag]
> dt
    record  x x.lag
 1:      1  1    NA
 2:      2  1     1
 3:      3 NA    NA
 4:      4  4    NA
 5:      5  5     4
 6:      6  6     5
 7:      7  6     6
 8:      8 NA    NA
 9:      9 NA    NA
10:     10 10    NA

1
不错的例子和方法。我也会考虑 dt[, x := x[1], by=cumsum(!is.na(x))](主要是因为我不习惯滚动连接)。 - Frank

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接