web-dev-qa-db-ja.com

その場でdata.tableからいくつかのランダムな行を抽出する方法

私は大きなdata.tableを持っています(約24000行以上)。いくつかの基準に基づいてそのデータテーブルをサブセット化し、そのサブセット(最終的には約3000行になる)から4つの行だけをランダムにサンプリングしたい。名前付きの3000などの行data.tableを作成したくないので、その行を数え、行番号に基づいてサンプリングします。どうすればその場でそれを行うことができますか?それとも、テーブルを作成して作業し、それをサンプリングしてから、rm()を使用してそれを取り除くことで、それを吸い込む必要がありますか?

私の問題をシミュレートしましょう

require(data.table)
random.length  <-  sample(x = 15:30, size = 1)
data.table(city=sample(c("Cape Town", "New York", "Pittsburgh", "Tel Aviv", "Amsterdam"), size=random.length, replace = TRUE), score = sample(x=1:10, size = random.length, replace=TRUE)) 

これにより、ランダムな長さのテーブルが作成されます。これは、基準と開始テーブルに応じて、サブセット化されたテーブルの長さがどの程度かわからないという事実をシミュレートします

さて、最初の3つの行が欲しいだけなら、そうすることができます

data.table(city=sample(c("Cape Town", "New York", "Pittsburgh", "Tel Aviv", "Amsterdam"), size=random.length, replace = TRUE), score = sample(x=1:10, size = random.length, replace=TRUE))[1:3]

しかし、最初の3行ではなくランダムな3行が必要だとすると、次のようなことをしたいと思います...

data.table(city=sample(c("Cape Town", "New York", "Pittsburgh", "Tel Aviv", "Amsterdam"), size=random.length, replace = TRUE), score = sample(x=1:10, size = random.length, replace=TRUE))[sample(x= 1:number of rows of that previous data.table,size = 3 ]

それはうまくいきません。オンザフライで、最初のdata.frameの長さを計算するにはどうすればよいですか?

27
Farrel

たった今.Niで動作します。新しいREADME item:

.NiFR#724 で利用可能になりました。初心者に間接的に感謝 ここ と直接Farrel ここ に感謝します。

これは今動作します:

DT[...][...][sample(.N,3)]

例えば.

> random.length  <-  sample(x = 15:30, size = 1)
> data.table(city = sample(c("Cape Town", "New York", "Pittsburgh", "Tel Aviv", "Amsterdam"),size=random.length, replace = TRUE), score = sample(x=1:10, size = random.length, replace=TRUE))[sample(.N, 3)] 
         city score
1:   New York     4
2: Pittsburgh     3
3:  Cape Town     9
> 
48
Matt Dowle

2つのステップのアプローチがあります。

  1. .Iを使用してインデックスiを計算します
  2. インデックスiのサンプル

コード例。

require(data.table)
random.length  <-  sample(x = 15:30, size = 1)
data.table(city = sample(c("Cape Town", "New York", "Pittsburgh", "Tel Aviv", "Amsterdam"),size=random.length, replace = TRUE), score = sample(x=1:10, size = random.length, replace=TRUE))[,i := .I][sample(i, 3)]
3
djhurio

別の代替方法は、sapplyアプローチを使用することです。
例えば:

  as.data.table(sapply(DT[], sample, 10))
1
Daniel