1

data.table がある場合

> DT1 <- data.table(A=rep(c('A', 'B'), 3),
                    B=rep(c(1,2,3), 2),
                    val=rnorm(6), key='A,B')
> DT1
   A B        val
1: A 1 -1.6283314
2: B 2  0.5337604
3: A 3  0.9991301
4: B 1  1.1421400
5: A 2  0.1230095
6: B 3  0.4988504

次のように、複数のキーでサブセット化したい:

> DT1[J('A', 1)]                                                               
   A B          val
1: A 1 -0.004898047

ただし、結合はキーの順序に依存するため、キー A の値は常に最初に来る必要があります。J()名前を (または としてlist())指定しても、これは機能しません。

> DT1[J(1, 'A')]
Error in `[.data.table`(DT1, J(1, "A")) : 
  x.'A' is a character column being joined to i.'V1' which is type 'double'. Character columns must join to factor or character columns.

> DT1[J(B=1, A='A')]
Error in `[.data.table`(DT1, J(B = 1, A = "A")) : 
  x.'A' is a character column being joined to i.'B' which is type 'double'. Character columns must join to factor or character columns.

iキーの順序を知らなくても、この種のグループ化を実行できる構文はありますか?

追加:別の使用例は、A ではなく B のみでサブセット化したい場合です。サブセット化でキーをスキップする方法はありますか? Jのラッパー関数を作成する現在の回答では、これが許可されていないようです。

編集: data.frame の方法でそれを行うと述べている人もいます。論理値のベクトルを使用してサブセット化できることは知っていますが、これはテーブル全体をスキャンするため遅くなります。

> DT1 <- data.table(A=rep(c(1,2,3), 100000), B=rep(c('A', 'B'), 150000), val=rnorm(300000), key='A,B')
> system.time(DT1[DT1$A==1, DT1$B=="A"])                                       
   user  system elapsed 
  0.080   0.000   0.054 
> system.time(DT1[J(1, 'A')])
   user  system elapsed 
  0.004   0.000   0.004 

関連する議論への参照: (1)

4

2 に答える 2

2

@フランクの答えの精神で、しかし自動的にキーを取得しようとしています:

myJ2 = function(...) {
  # 'x' a couple of frames above is where the original data.table sits
  data.table(..., key = key(get('x', parent.frame(n = 3))))
}

DT1[myJ2(B=1, A='A')]
#   A B       val
#1: A 1 0.4328698
于 2013-08-14T20:42:00.993 に答える