2014-12-05 42 views
4

此問題與How do you sample random rows within each group in a data.table?非常相似。如何在data.table中對組進行採樣,並提出警告

不同之處在於我沒有足夠的信譽來討論這個問題本身。

,讓我們改變克里斯托弗·曼寧的初始數據一點點:

> DT = data.table(a=c(1,1,1,1:15,1,1), b=sample(1:1000,20)) 
> DT 
    a b 
1: 1 102 
2: 1 5 
3: 1 658 
4: 1 499 
5: 2 632 
6: 3 186 
7: 4 761 
8: 5 150 
9: 6 423 
10: 7 832 
11: 8 883 
12: 9 247 
13: 10 894 
14: 11 141 
15: 12 891 
16: 13 488 
17: 14 101 
18: 15 677 
19: 1 400 
20: 1 467 

如果我們嘗試了問題的解決方案:

> DT[,.SD[sample(.N,3)],by = a] 
Error in sample.int(x, size, replace, prob) : 
    cannot take a sample larger than the population when 'replace = FALSE' 

這是因爲在列值是隻出現一次。如果不使用替換(我們不想這麼做),我們不能對三次以內的值進行3次採樣。

我正在努力處理這種情況。我們想品嚐的3倍時,出現的次數爲> = 3,但拉發生的次數,如果它是< 3。例如我們的DT上面我們會想:

 a b 
1: 1 102 
2: 1 5 
3: 1 658 
4: 2 632 
5: 3 186 
6: 4 761 
7: 5 150 
8: 6 423 
9: 7 832 
10: 8 883 
11: 9 247 
12: 10 894 
13: 11 141 
14: 12 891 
15: 13 488 
16: 14 101 
17: 15 677 

可能的解決方案可能涉及sorting的data.table這個樣子,然後用rle()lengths找出在上面的示例函數要使用的n

> DT <- DT[order(DT$a),] 
> DT 
    a b 
1: 1 102 
2: 1 5 
3: 1 658 
4: 1 499 
5: 1 400 
6: 1 467 
7: 2 632 
8: 3 186 
9: 4 761 
10: 5 150 
11: 6 423 
12: 7 832 
13: 8 883 
14: 9 247 
15: 10 894 
16: 11 141 
17: 12 891 
18: 13 488 
19: 14 101 
20: 15 677 

> ifelse(rle(DT$a)$lengths >= 3, 3,rle(DT$a)$lengths) 
> [1] 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 

如果我們將「3」 N,這將返回我們應該有多少來自樣a = 1,a = 2,a = 3 ... 我還沒有找到aw可以將其納入最終解決方案。任何幫助,將不勝感激!

回答

8

我可能會誤解你的問題,但你在尋找類似的東西嗎?

set.seed(123) 
## 
DT <- data.table(
    a=c(1,1,1,1:15,1,1), 
    b=sample(1:1000,20)) 
## 
R> DT[,.SD[sample(.N,min(.N,3))],by = a] 
    a b 
1: 1 288 
2: 1 881 
3: 1 409 
4: 2 937 
5: 3 46 
6: 4 525 
7: 5 887 
8: 6 548 
9: 7 453 
10: 8 948 
11: 9 449 
12: 10 670 
13: 11 566 
14: 12 102 
15: 13 993 
16: 14 243 
17: 15 42 

在那裏我們繪製3個樣品從b爲組a_i如果a_i包含三個或更多個值,否則,我們只繪製n值,其中nn < 3)是組a_i的大小。

只是爲了演示,這裏是ba=1,我們從(假設你用上述同樣的隨機種子)取樣6個可能的值:

R> DT[order(a)][1:6,] 
    a b 
1: 1 288 
2: 1 788 
3: 1 409 
4: 1 881 
5: 1 323 
6: 1 996 
+2

這是完美的。我完全解決了這個問題。盯着電腦屏幕整天都可以做到這一點,你我猜... – 2014-12-05 23:11:47

+1

我想你應該發佈這個答案以及其他問題。我想,但是我會拿你的信用! 此解決方案是對所鏈接問題的更一般解決方案。謝謝! – 2014-12-06 01:17:53