2016-01-18 37 views
3

我想在data.table列中使用下面的值使用shift缺少值,但是我只能讓它工作,如果我第一次創建一個臨時變量。這是預期的行爲? MWE:R data.table:用shift()更新不能按預期工作

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 
+0

當你在DT [i,j]的'i'中過濾時,'j'只對這個子集起作用。所以這是預期的行爲。不過,很好的例子。我希望看到擴展的功能更好地處理這種情況,比如'DT [,x [is.na(x)]:= shift(x)]'或者其他什麼。 – Frank

回答

2

我有點新data.table,但我覺得滾動加入可能是你在這裏後在做什麼。假設您希望能夠在有多個缺少值的順序時對數據點進行歸一化處理,在這種情況下,您的方法將只填充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 

比起你的方法產生以下(的完整列表上滾向前)仍具有值);

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