2

私は(完全に素晴らしい)data.tableパッケージにまったく慣れていないので、非常に基本的でやや奇妙な問題に悩まされているようです。私が作業している正確なデータセットを投稿することはできませんが、それについてはお詫び申し上げます.

キー x を使用して、次のような data.table があるとします。

set1
   x y
1: 1 a
2: 1 b
3: 1 c
4: 2 a

set1すべての行を含む のサブセットを返したいx == 1. これは、data.table: では驚くほど単純ですset1[J(1)]。バム。終わり。を割り当てz <- 1たり、呼び出したりすることもできますset1[J(z)]。繰り返しますが、うまくいきます。

...最大6M行を含む実際のデータセットにスケールアップしようとした場合を除きます。を呼び出すとset1[J(1674)]、まさに探していた 78 行の戻り値が返されます。しかし、(文字通り) 4M のこれらのサブセットを検索できる必要があります。検索している値を変数に代入すると、id <- 1674、および呼び出しset1[J(id)]... R は私のデスクトップをほとんどダウンさせます。

明らかに、私が理解できないことが data.table フードの下で起こっていますが、何が起こっているのかわかりませんスタックオーバーフローによるグーグルとスローグは、これが機能することを示唆しています。純粋な気まぐれから、私は試しました:

id <- quote(1674)
set1[J(eval(id))]

...しかし、それははるかに悪いです。なに…どうしたの?

4

1 に答える 1

3

[ @mnel は、私が書いているときに私を打ちのめしました ...]

ほぼ確実に、 の 1 つの列がset1たまたま呼び出され"id"ます。つまり、

isTRUE("id" %in% names(set1))

呼び出しスコープを無視して、set1[J(id)]に自己参加set1$idさせます。set1id

その場合、次のようなスコープの問題を回避するためのいくつかのアプローチがあります。

.id = <your 4M ids>
set1[J(.id)]

iまたは、スコープの呼び出しで単一の名前が評価されるという事実を使用します。

JDT=J(id); set1[JDT]

または、それevaleval呼び出しスコープで 'd です:

set1[eval(J(id))]

または、これをより明確にし、より堅牢で簡単にしたいので、1つの考えは追加すること..です:

set1[..(J(id))]     # .. alias for eval

多分 :

set1[J(..id)]

where..は、ファイル システムの からその意味を借用しており..、1 レベル上を意味します。がシンボルのプレフィックスである場合、次の..ようなことができます。

DT[colB==..id]

where==は説明のために使用されています。その例colBでは、列名であると予想され、呼び出しスコープ (1 レベル上) で..id検索されます。idプログラマーが意図したことは、コードの読者にとって非常に明確になると考えられています。

于 2012-12-17T21:52:48.123 に答える