2016-07-23 16 views
2

我有一個list類型data.table:R數據表:表型的換檔行

x = data.table(k = seq(1:5), l = list(c(4,5))) 
> x 
    k l 
1: 1 4,5 
2: 2 4,5 
3: 3 4,5 
4: 4 4,5 
5: 5 4,5 

我現在想通過1l價值觀轉變:

x[, m:=shift(l, 1)] 
> x 
    k l  m 
1: 1 4,5 NA, 4 
2: 2 4,5 NA, 4 
3: 3 4,5 NA, 4 
4: 4 4,5 NA, 4 
5: 5 4,5 NA, 4 

這在列表中「產生了一個移位,而不是在列表中移動(除此之外:目前還不清楚爲什麼NA出現在第2-5列。) 這樣做的方式是什麼:

x[magic] 
> x 
    k l m 
1: 1 4,5 NA 
2: 2 4,5 4,5 
3: 3 4,5 4,5 
4: 4 4,5 4,5 
5: 5 4,5 4,5 
+0

自從[最近實施了一個更好的解決方案]後將其作爲dup結尾(https://github.com/Rdatatable/data.table/issues/1595)。 – Arun

回答

3

您可以使用手動班次,如下所示。

x[, m := c(NA_real_, head(l, -1L))] 

導致

k l m 
1: 1 4,5 NA 
2: 2 4,5 4,5 
3: 3 4,5 4,5 
4: 4 4,5 4,5 
5: 5 4,5 4,5 

對於一個較大的轉變,你可以滾你自己的功能。

mshift <- function(var, n) c(NA[1:n], head(var, -n)) 

然後用它來換兩個地方。

x[, m := mshift(l, 2)] 

賦予,從原始數據

k l m 
1: 1 4,5 NA 
2: 2 4,5 NA 
3: 3 4,5 4,5 
4: 4 4,5 4,5 
5: 5 4,5 4,5 

顯然,這個功能是非常基本的,只向右移動(向下)。如果你想,你可以調整函數向相反的方向移動,並添加一些類檢查/匹配。

+0

也許'NA_real_'與其餘的匹配。 – Frank

+1

@Frank - 我想是這樣,即使列表元素通常不相關。 –

2

隨着shift,一種選擇是讓在「L」的序列shift,子集基礎上的「L」,並將其分配給新列「M」。默認情況下,shiftfill = NA返回。因此,這些元素將在'm'中爲NULL,我們可以將其replaceNA(如果需要),或者使用is.null也可以很容易地刪除這些元素。

x[, m := l[shift(seq_along(l))]][, m := lapply(m, function(x) 
      replace(x, is.null(x), NA))] 
x 
# k l m 
#1: 1 4,5 NA 
#2: 2 4,5 4,5 
#3: 3 4,5 4,5 
#4: 4 4,5 4,5 
#5: 5 4,5 4,5 

或者正如@Frank提到的,我們可以指定在邏輯索引,同時更新的「m」到NA_real_僅在指定的元素的那些子集的「i」的「i」的並且將是更有效的。

x[, m := l[shift(seq_along(l))]][sapply(m, is.null), m := .(.(NA_real_))] 

或者以緊湊的方式,我們可以改變fill0,並在開始追加NA。如果shift大於1,則使用rep複製NA並在開始處追加。

x[, m:= c(NA, l[shift(seq_along(l), fill = 0)])] 
+0

感謝您的回答,但喜歡@Richard的簡潔。你更好地評價你的答案嗎? – jacquard

+0

@jacquard我選擇這個是因爲你的問題是關於使用'shift',否則,我會選擇更簡單的選項。 – akrun

+0

好吧,我的問題是關於總體移動看我的問題'魔術'參考。我選擇理查德的答案是因爲簡單而被接受。乾杯! – jacquard