2014-04-25 73 views
4

我想從一個data.table聚合一個數據來創建一個新的列,這是一個前面的行列表。它更容易通過例子來看看:data.table聚合列表列

dt <- data.table(id = c(1,1,1,1,2,2,3,3,3), letter = c('a','a','b','c','a','c','b','b','a')) 

我想在這樣的方式,其結果應該是

id letter 
1: 1 a,a,b,c 
2: 2  a,c 
3: 3 b,b,a 

憑直覺我試圖

dt[,j = list(list(letter)), by = id] 

聚合這一點,但說沒有按」工作。奇怪的是,當我的話,請情況下,例如:

> dt[id == 1,j = list(list(letter)), by = id] 

    id  V1 
1: 1 a,a,b,c 

結果是好的......我覺得我缺少一個.SD某處或類似的東西...

任何人可以點我在正確的方向?

謝謝!

回答

5

更新:行爲DT[, list(list(.)), by=.]有時會導致R版本> = 3.1.0中的錯誤結果。現在在data.table v1.9.3的當前開發版本中現在修復了commit #1280。從NEWS

  • DT[, list(list(.)), by=.]回報中的R正確結果> = 3.1.0爲好。該錯誤是由於R v3.1.0中最近(歡迎)的更改造成的,其中list(.)未導致副本。關閉#481

安裝此更新,這是沒有必要I()了。您可以像以前那樣執行:DT[, list(list(.)), by=.]


這似乎與已知的bug #5585類似的問題。在你的情況,我認爲你可以只使用

dt[, paste(letter, collapse=","), by = id] 

來解決你的問題。

由於@ilir指出的那樣,如果它實際上是希望得到一個列表(而不是顯示的字符),你可以使用bug報告建議的解決方法:

dt[, list(list(I(letter))), by = id] 
+0

upvoted,打我吧..儘管這不會返回變量名稱「letter」 –

+0

這個問題是因爲'list(。)'在R3.1.0中淺拷貝。將在下一個版本中修復。 – Arun

+0

很想知道原因。謝謝Arun。我發現了另一種使用'.SD'的方法,但它的工作原理是一樣的。我沒有對運行時間進行基準測試,看看哪個更好。 – MagicScout

1

的語法如下工程me:

dt[, list(lst=list(letter)), by=id] 

我正在使用R版本3.0.3,data.table_1.9.2。

+0

它是否真的給出了預期的結果?對我來說,它只是給所有id的'b,b,a,c'。使用R 3.1.0,data.table_1.9.2 – shadow

+0

它適用於我。 –

+0

在我的版本上按預期工作。它一定是@shadow指出的錯誤。錯誤報告也有一個解決方法。 – ilir