2017-04-07 3 views
3

究極の目的は、1ワードにつき10サンプルのインクリメンタルサイズのランダムサンプルのavg_scoreからの単純統計(分子/分母/真数)の分散と標準偏差を類似したデータセット:データフレーム行を一意の列値で無作為にサンプルする方法

library (data.table) 
set.seed(1) 
df <- data.frame(
    word_ID = c(rep(1,4),rep(2,3),rep(3,2),rep(4,5),rep(5,5),rep(6,3),rep(7,4),rep(8,4),rep(9,6),rep(10,4)), 
    word = c(rep("cat",4), rep("house", 3), rep("sung",2), rep("door",5), rep("pretty", 5), rep("towel",3), rep("car",4), rep("island",4), rep("ran",6), rep("pizza", 4)), 
    true_count = c(rep(234,4),rep(39,3),rep(876,2),rep(4,5),rep(67,5),rep(81,3),rep(90,4),rep(43,4),rep(54,6),rep(53,4)), 
    occurrences = c(rep(234,4),rep(34,3),rep(876,2),rep(4,5),rep(65,5),rep(81,3),rep(90,4),rep(43,4),rep(54,6),rep(51,4)), 
    item_score = runif(40), 
    avg_score = rnorm(40), 
    line = c(71,234,71,34,25,32,573,3,673,899,904,2,4,55,55,1003,100,432,100,29,87,326,413,32,54,523,87,988,988,12,24,754,987,12,4276,987,93,65,45,49), 
    validity = sample(c("T", "F"), 40, replace = T) 

) 
dt <- data.table(df) 
dt[ , denominator := 1:.N, by=word_ID] 
dt[ , numerator := 1:.N, by=c("word_ID", "validity")] 
dt$numerator[df$validity=="F"] <- 0 
df <- dt 

<df 
    word_ID word true_count occurrences item_score avg_score line validity denominator numerator 
1:  1 cat  234   234 0.25497614 0.15268651 71  F   1   0 
2:  1 cat  234   234 0.18662407 1.77376261 234  F   2   0 
3:  1 cat  234   234 0.74554352 -0.64807093 71  T   3   1 
4:  1 cat  234   234 0.93296878 -0.19981748 34  T   4   2 
5:  2 house   39   34 0.49471189 0.68924373 25  F   1   0 
6:  2 house   39   34 0.64499368 0.03614551 32  T   2   1 
7:  2 house   39   34 0.17580259 1.94353631 573  F   3   0 
8:  3 sung  876   876 0.60299465 0.73721373 3  T   1   1 
9:  3 sung  876   876 0.88775767 2.32133393 673  F   2   0 
10:  4 door   4   4 0.49020940 0.34890935 899  T   1   1 
11:  4 door   4   4 0.01838357 -1.13391666 904  T   2   2 

データは、文書内の単語のそれぞれの検出を表し、それは、複数回同じ行に表示される単語のために可能です。このタスクは、サンプルサイズが一意の列の値(line)を表しますが、行番号が同じであるすべてのインスタンスを返すことです。つまり、実際に返される行の数が指定したサンプルサイズを超える可能性があります。だから、「猫」のための1つの2ワードのサンプルサイズの試験のために、望ましい結果の形式は次のようになります。

for (i in 1:10) { 

    a2[[i]] <- lapply(split(df, df$word_ID), function(x) x[sample(nrow(x), 2, replace = T), ]) 

    b3[[i]] <- lapply(split(df, df$word_ID), function(x) x[sample(nrow(x), 3, replace = T), ])} 

} 

word_ID word true_count occurrences item_score avg_score line validity denominator numerator 
1:  1 cat  234   234 0.25497614 0.15268651 71  F   1   0 
2:  1 cat  234   234 0.18662407 1.77376261 234  F   2   0 
3:  1 cat  234   234 0.74554352 -0.64807093 71  T   3   1 

(このサイトで見つけた)私の基本的な反復は、現在のようになります。

したがって、私は標準の無作為標本サイズを行うことができますが、上記の目標に近づける方法は不明です(同様のものを見つけることができず、正しい方法を見ていない)。これにアプローチする簡単な方法はありますか?ここで

おかげで、

答えて

3

は、サンプリングされたdata.tableに参加を使用していますdata.tableソリューションです。

set.seed(1234) 
df[df[, .(line=sample(unique(line), 2)), by=word], on=.(word, line)] 

内側のdata.tableはwordとlineの2つの列で構成され、wordごとに2つの行があり、それぞれに行の一意の値があります。行の値はsampleによって返され、行の一意の値が入力され、単語ごとに個別に実行されます(by=wordを使用)。一意の行の数を変更するには、2を目的の値に変更します。このdata.tableは、目的の行を選択するためにメインのdata.tableに結合されています。この場合

、あなたが重複除外data.frameからサンプリングして、その後、元のデータと左ジョインない場合、あなたはあなたが必要なものを確保することができます

word_ID word true_count occurrences item_score avg_score line validity 
1:  1 cat  234   234 0.26550866 0.91897737 71  F 
2:  1 cat  234   234 0.57285336 0.07456498 71  T 
3:  1 cat  234   234 0.37212390 0.78213630 234  T 
4:  2 house   39   34 0.89838968 -0.05612874 32  T 
5:  2 house   39   34 0.94467527 -0.15579551 573  F 
6:  3 sung  876   876 0.62911404 -0.47815006 673  T 
7:  3 sung  876   876 0.66079779 -1.47075238 3  T 
8:  4 door   4   4 0.06178627 0.41794156 899  F 
9:  4 door   4   4 0.38410372 -0.05380504 55  F 
10:  5 pretty   67   65 0.71761851 -0.39428995 100  F 
11:  5 pretty   67   65 0.38003518 1.10002537 100  F 
12:  5 pretty   67   65 0.49769924 -0.41499456 1003  F 
13:  6 towel   81   81 0.21214252 -0.25336168 326  F 
14:  6 towel   81   81 0.93470523 -0.16452360 87  F 
15:  7 car   90   90 0.12555510 0.55666320 32  T 
16:  7 car   90   90 0.26722067 -0.68875569 54  F 
17:  8 island   43   43 0.01339033 0.36458196 87  T 
18:  8 island   43   43 0.38238796 0.76853292 988  F 
19:  8 island   43   43 0.86969085 -0.11234621 988  T 
20:  9 ran   54   54 0.59956583 -0.61202639 754  F 
21:  9 ran   54   54 0.82737332 1.43302370 4276  F 
22:  10 pizza   53   51 0.79423986 -0.36722148 93  F 
23:  10 pizza   53   51 0.41127443 -0.13505460 49  T 
    word_ID word true_count occurrences item_score avg_score line validity 
+1

47秒...しかし、私の基盤はあなたのものが 'data.table'なので、補足として私の答えを保ちます。 – r2evans

+0

これらはきわめて明確な方法のように見え、基本回答が多いほど良い。 – lmo

+0

私は 'data.table'を学ぶことを意味してきました。私は、ベース(これは私が認識している)が類似の非ベースソリューションとペアになっているのを見てよく分かります。だから、私にとっては、両方を見ることは完全に関連しています。ありがとうございました:-) – r2evans

2

を取得します。

私はdata.tableに堪能ではないので、基本機能を使用します。 (dplyrもここでもうまくいくでしょうが、data.tableを使用しているので、今は避けています)。(私が提出するヒットのように@lmoはdt固有の答えを提供しました...)

"脱重複" と

は、私が意味:

df[1:4,] 
# word_ID word true_count occurrences item_score avg_score line validity 
# 1  1 cat  234   234 0.2655087 0.91897737 71  F 
# 2  1 cat  234   234 0.3721239 0.78213630 234  T 
# 3  1 cat  234   234 0.5728534 0.07456498 71  T 
# 4  1 cat  234   234 0.9082078 -1.98935170 34  T 

私はここにbyを使用しています:元のデータが4を持っているのに対し、subdfのみ、1のための3つの行を持っていることを

subdf <- df[,c("word_ID", "line")] 
subdf <- subdf[!duplicated(subdf),] 
dim(subdf) 
# [1] 36 2 
head(subdf) 
# word_ID line 
# 1  1 71 
# 2  1 234 
# 4  1 34 
# 5  2 25 
# 6  2 32 
# 7  2 573 

注意をlapply/splitの代わりに結果は同じでなければなりません:

out <- by(subdf, subdf$word_ID, function(x) merge(x[sample(nrow(x), 2, replace=TRUE),], df, by=c("word_ID", "line"))) 
out[1] 
# $`1` 
# word_ID line word true_count occurrences item_score avg_score validity 
# 1  1 34 cat  234   234 0.9082078 -1.98935170  T 
# 2  1 71 cat  234   234 0.5728534 0.07456498  T 
# 3  1 71 cat  234   234 0.2655087 0.91897737  F 
関連する問題