7

j関数が呼び出しごとに異なる数の列を返すことができるdata.table を使用しようとしています。rbind.fill不足している列をNA.

fetch <- function(by) {
    if(by == 1)
        data.table(A=c("a"), B=c("b"))
    else
        data.table(B=c("b"))
}
data <- data.table(id=c(1,2))
result <- data[, fetch(.BY), by=id]

この場合、'result' は 2 つの列になる可能性があります。A と B。'A' と 'B' は 'fetch' への最初の呼び出しの一部として返され、'B' のみが 2 番目の呼び出しの一部として返されました。サンプルコードがこの結果を返すようにしたいと思います。

  id    A B
1  1    a b
2  2 <NA> b

残念ながら、実行するとこのエラーが発生します。

Error in `[.data.table`(data, , fetch(.BY, .SD), by = id) : 
j doesn't evaluate to the same number of columns for each group

次のようにこれを行うことができますplyrが、実際のユースケースplyrではメモリが不足しています。への各呼び出しはかなり迅速に行われますが、すべてのデータをマージして戻そうとするとfetchメモリ クラッシュが発生します。この問題を解決plyrできるかどうかを確認しようとしています。data.table

result <- ddply(data, "id", fetch)

どんな考えでも大歓迎です。

4

3 に答える 3

7

DWin のアプローチは優れています。listまたは、代わりに、各セル自体がベクトルである列を返すこともできます。これは一般に、可変長ベクトルを処理するためのより良い方法です。

DT = data.table(A=rep(1:3,1:3),B=1:6)
DT
   A B
1: 1 1
2: 2 2
3: 2 3
4: 3 4
5: 3 5
6: 3 6
ans = DT[, list(list(B)), by=A]
ans
   A    V1
1: 1     1
2: 2   2,3     # V1 is a list column. These aren't strings, the
3: 3 4,5,6     # vectors just display with commas

ans$V1[3]
[[1]]
[1] 4 5 6

ans$V1[[3]]
[1] 4 5 6

ans[,sapply(V1,length)]
[1] 1 2 3

したがって、あなたの例では、これを次のように使用できます。

library(plyr)

rbind.fill(data[, list(list(fetch(.BY))), by = id]$V1)
#     A B
#1    a b
#2 <NA> b

または、返されたリストを適合させます。

allcols = c("A","B")
fetch <- function(by) {
    if(by == 1)
        list(A=c("a"), B=c("b"))[allcols]
    else
        list(B=c("b"))[allcols]
}
于 2013-09-26T19:29:02.183 に答える
3

試す

            data.table(A=NA, B=c("b"))

@NickAllen: コメントから、あなたが私の提案を理解したかどうかわかりません。(カットペースト機能が制限された携帯電話から投稿していたのですが、妻がS0へのテキストメッセージをやめるように言っているのではないかと思います。そうしないと離婚します.)私が言いたかったことは次のとおりです。

fetch <- function(by) {
    if(by == 1)
        data.table(A=c("a"), B=c("b"))
    else
        data.table(A=NA, B=c("b"))
}
data <- data.table(id=c(1,2))
result <- data[, fetch(.BY), by=id]
于 2013-09-26T19:14:36.993 に答える