假设我们有两个表,每个表之间都有一个共同的组指示符。然后,对于DT1中的每一行,我们想从DT2中的每组中随机选择2行。
解决此问题的一种可能方法是在DT2中随机生成一个与DT1的行重合的整数列,并将两个表连接在一起。但是行的数量因组而异,目前尚不清楚如何根据组的长度来进行限制。
最小工作示例:
DT1 <- data.table(var1=seq(1:20),
group=c(1,1,1,1,1,2,2,2,2,3,3,3,4,4,4,4,4,4,4,4))
DT2 <- data.table(obs=seq(1:13),
group=c(1,1,1,2,2,2,3,3,3,4,4,4,5))
查看:
DT1
var1 group
1: 1 1
2: 2 1
3: 3 1
4: 4 1
5: 5 1
6: 6 2
7: 7 2
8: 8 2
9: 9 2
10: 10 3
11: 11 3
12: 12 3
13: 13 4
14: 14 4
15: 15 4
16: 16 4
17: 17 4
18: 18 4
19: 19 4
20: 20 4
DT2
obs group
1: 1 1
2: 2 1
3: 3 1
4: 4 2
5: 5 2
6: 6 2
7: 7 3
8: 8 3
9: 9 3
10: 10 4
11: 11 4
12: 12 4
13: 13 5
因此,对于DT1中的每一行,我想将其与DT2中随机选择的2行按组进行配对。预期的结果可能类似于:
DT3
var1 group obs
1: 1 1 1
2: 1 1 3
3: 2 1 2
4: 2 1 3
...
37: 19 4 10
38: 19 4 11
39: 20 4 10
40: 20 4 12
如果需要说的话,实际应用程序在DT1中有4亿行,在DT2中有1000万行。
答案 0 :(得分:3)
您的需求的直接翻译是:
DT2[DT1, on=.(group), allow.cartesian=TRUE, .(var1, obs=obs[sample(.N, 2L)]), by=.EACHI]
这可能会更快:
gn <- DT1[, .(nsamp=2*.N), keyby=.(group)]
DT2[gn, on=.(group), .(obs=obs[sample(.N, nsamp, replace=TRUE)]), by=.EACHI][,
var1 := rep(DT1$var1, each=2L)]
数据:
set.seed(0L)
library(data.table)
DT1 <- data.table(var1=101:120, group=c(1,1,1,1,1,2,2,2,2,3,3,3,4,4,4,4,4,4,4,4))
DT2 <- data.table(obs=201:213, group=c(1,1,1,2,2,2,3,3,3,4,4,4,5))
示例输出:
group var1 obs
1: 1 101 203
2: 1 101 201
3: 1 102 202
4: 1 102 203
5: 1 103 203
6: 1 103 201
7: 1 104 203
8: 1 104 202
9: 1 105 202
10: 1 105 203
11: 2 106 204
12: 2 106 206
13: 2 107 204
14: 2 107 205
15: 2 108 205
16: 2 108 206
17: 2 109 205
18: 2 109 206
19: 3 110 209
20: 3 110 207
21: 3 111 209
22: 3 111 208
23: 3 112 207
24: 3 112 208
25: 4 113 210
26: 4 113 212
27: 4 114 211
28: 4 114 210
29: 4 115 211
30: 4 115 212
31: 4 116 211
32: 4 116 210
33: 4 117 211
34: 4 117 210
35: 4 118 210
36: 4 118 211
37: 4 119 212
38: 4 119 211
39: 4 120 210
40: 4 120 211
group var1 obs
答案 1 :(得分:2)
这是使用dplyr
的一种方法,我相信这也可以转换为data.table
。逻辑是我们首先计算DT1
中每个组的行数,left_join
将DT2
到group
并使用sample
随机选择{{1 }}行中的每个n * 2
。
group