3

私は次のものを持っています:

test <- data.table(id=1:11, t=c(rep(1:2,5), 3))
test[length(unique(id))>1,list(id, t), by=t]

    id t
 1:  1 1
 2:  2 2
 3:  3 1
 4:  4 2
 5:  5 1
 6:  6 2
 7:  7 1
 8:  8 2
 9:  9 1
10: 10 2
11: 11 3

私はこれがグループtest化され、各グループのステートメントをt評価し、trueの行を返すことを期待していました(つまり、複数の一意のIDがあります)。代わりに返されるのはこれです:ji

> test
     id t
 1:  1 1
 2:  2 2
 3:  3 1
 4:  4 2
 5:  5 1
 6:  6 2
 7:  7 1
 8:  8 2
 9:  9 1
10: 10 2  
11: 11 3

にのみ適用され、にはby適用されないようです。ここに何か提案はありますか?ji

4

1 に答える 1

5

正しいか間違っているかを問わず、i最初にj実行され、次にby通過するすべての行で実行されますi

一般的なイディオムは次のようなものです(SQLのHAVINGに似ています):

test[,list(id, u=length(unique(id))), by=t][u>1]

u結果から(各グループ内の一意のIDの数)を除外します。

test[,list(id, u=length(unique(id))), by=t][u>1][,u:=NULL]

ところで、i(はるかに小さい)集計結果(u>1上記の行など)でベクトルスキャンを実行する方が、(はるかに大きい)元のデータでベクトルスキャンを実行するよりもはるかに効率的です。

データセット全体でj実行され、その後に結果(予想どおり)が続く場合、効率に問題が発生します。それがそのように機能したかどうかを検討してください。次に、最初にフィルターを実行し、次に結果をグループ化するために、次の2つの呼び出しに分割する必要があります。次に、 (内で)表示されず、必要な列もわかりません。これを1つに組み合わせると、評価前に検査し、必要な列のみをサブセット化できます。これにより、列の小さなサブセットを使用するクエリの大きなデータセットに非常に大きな違いが生じます。byi[DT[i][,j,by]ij[.data.tableDT[i,j,by]ijj


何が起こったのかを見るには、あなたiを連れて行ってくださいj

test[,length(unique(id))>1]  
# [1] TRUE

その後、シングルTRUEはリサイクルされました。DT[TRUE] == DTiそのようにすることでいつでもテストできますj

于 2012-08-20T16:38:37.710 に答える