8

パッケージからdata.table作成されたデータフレームの構造に似た構造を持つオブジェクトを操作するためのパターンを探しています。何百万行ものデータテーブルを扱っています。パフォーマンスは重要です。meltreshape2

質問の一般化された形式は、列内の値のサブセットに基づいてグループ化を実行し、グループ化操作の結果で 1 つ以上の新しい列を作成する方法があるかどうかです。

質問の特定の形式は、次data.tableのことと同等のことを達成するために使用する方法である可能性があります。dcast

input <- data.table(
  id=c(1, 1, 1, 2, 2, 2, 3, 3, 3, 3), 
  variable=c('x', 'y', 'y', 'x', 'y', 'y', 'x', 'x', 'y', 'other'),
  value=c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
dcast(input, 
  id ~ variable, sum, 
  subset=.(variable %in% c('x', 'y')))

その出力は

  id  x  y
1  1  1  5
2  2  4 11
3  3 15  9
4

3 に答える 3

9

テストされていない簡単な答え: by-without-by、別名grouping-by-iを探しているようです :

setkey(input,variable)
input[c("x","y"),sum(value)]

これは、SQLの高速HAVINGのようなものです。jの各行に対して評価されますi。言い換えれば、上記は同じ結果ですが、よりもはるかに高速です:

input[,sum(value),keyby=variable][c("x","y")]

関心のあるグループのみを選択する前に、すべてのグループの後者のサブセットと評価(無駄に)。前者(by-without-by)は、グループのサブセットにのみ直接適用されます。

グループの結果は、いつものように長い形式で返されます。ただし、後で(比較的小さい)集約データをワイドに再形成するのは比較的瞬時に行う必要があります。それはとにかく考えです。

関心のない列がたくさんある場合、最初のものsetkey(input,variable)は噛む可能性があります。inputもしそうなら、必要な列をサブセット化する価値があるかもしれません:

DT = setkey(input[ , c("variable","value")], variable)
DT[c("x","y"),sum(value)]

将来、セカンダリキーが実装されると、より簡単になります。

set2key(input,variable)              # add a secondary key 
input[c("x","y"),sum(value),key=2]   # syntax speculative

id同様にグループ化するには:

setkey(input,variable)
input[c("x","y"),sum(value),by='variable,id']

データに応じてid、キーに含めることはコストに見合う価値があるかもしれません。setkey

setkey(input,variable,id)
input[c("x","y"),sum(value),by='variable,id']

上記のように、by-without-byとbyを組み合わせると、by-without-byはサブセットのように動作します。つまり、byが欠落している場合jの各行に対してのみ実行されます(したがって、 by-without-byという名前)。したがって、上記のように、を含める必要があります。ivariableby

または、代わりに「x」と「y」の和集合を超えてグループ化する必要idがあります(ただし、上記は質問iiucで求めたものです)。

input[c("x","y"),sum(value),by=id]
于 2012-12-20T10:13:47.847 に答える
3
> setkey(input, "id")
> input[ , list(sum(value)), by=id]
   id V1
1:  1  6
2:  2 15
3:  3 34

> input[ variable %in% c("x", "y"), list(sum(value)), by=id]
   id V1
1:  1  6
2:  2 15
3:  3 24

最後のもの:

> input[ variable %in% c("x", "y"), list(sum(value)), by=list(id, variable)]
   id variable V1
1:  1        x  1
2:  1        y  5
3:  2        x  4
4:  2        y 11
5:  3        x 15
6:  3        y  9
于 2012-12-20T09:17:42.863 に答える
2

これが最善の方法かどうかはわかりませんが、試すことができます:

input[, list(x = sum(value[variable == "x"]), 
             y = sum(value[variable == "y"])), by = "id"]
#    id  x  y
# 1:  1  1  5
# 2:  2  4 11
# 3:  3 15  9
于 2012-12-20T09:34:03.390 に答える