9

data.tableパッケージを使用して、入力に表示されない変数の組み合わせを保持するデータを要約することは可能ですか?

plyrパッケージでは、.drop 引数を使用してこれを行う方法を知っています。たとえば、次のようになります

require(plyr)
df <- data.frame(categories = c(rep("A",3), rep("B",3), rep("C",3)), groups = c(rep(c("X", "Y"),4), "Z"), values = rep(1, 9))

df1 <- ddply(df, c("categories","groups"), .drop = F, summarise, sum = sum(values))

出力:

 categories groups sum
1          A      X   2
2          A      Y   1
3          A      Z   0
4          B      X   1
5          B      Y   2
6          B      Z   0
7          C      X   1
8          C      Y   1
9          C      Z   1

この場合、合計が 0 であっても、すべてのグループ/カテゴリの組み合わせを保持します。

4

1 に答える 1

9

素晴らしい質問です。ここに2つの方法があります。どちらも by-without-by を使用します。

DT = as.data.table(df)
setkey(DT,categories,groups)
DT[CJ(unique(categories),unique(groups)), sum(values,na.rm=TRUE)]

   categories groups V1
1:          A      X  2
2:          A      Y  1
3:          A      Z  0
4:          B      X  1
5:          B      Y  2
6:          B      Z  0
7:          C      X  1
8:          C      Y  1
9:          C      Z  1

CJCross Join を表します。 を参照してください?CJ。by-without-by は、各行が結合するj各グループで実行されることを意味します。i

確かに、一見するとトリッキーに見えます。グループの既知のサブセットがある場合、この構文は、すべてをグループ化してから必要な結果だけを選択するよりも高速です。ただし、この場合はとにかくすべてが必要なので、データに存在しないグループを検索できること以外に大きな利点はありません (これは ではできませんby)。

もう 1 つの方法は、by最初は通常どおり、次にCJ()結果をそれに結合することです。

DT[,sum(values),keyby='categories,groups'][CJ(unique(categories),unique(groups))]
   categories groups V1
1:          A      X  2
2:          A      Y  1
3:          A      Z NA
4:          B      X  1
5:          B      Y  2
6:          B      Z NA
7:          C      X  1
8:          C      Y  1
9:          C      Z  1

しかし、その後、目的の 0 の代わりに NA を取得します。これらは、必要に応じて使用して置き換えることができset()ます。unique2 番目の方法は、2 つの呼び出しに与えられる入力がはるかに小さいため、高速になる可能性があります。

これを頻繁に行う場合、両方のメソッドを小さなヘルパー関数にまとめることができます。

于 2013-01-23T18:16:48.807 に答える