【发布时间】:2017-10-23 02:25:38
【问题描述】:
我正在尝试为每个处理过的观察找到最接近的值。数据如下(1.2M obs的部分数据):
> dta
id treatment score
1: 5 0 0.02381024
2: 10 0 0.05428605
3: 22 0 0.02118124
4: 27 0 0.01495214
5: 45 0 0.01877916
6: 50 0 0.02120360
7: 58 0 0.02207263
8: 60 0 0.02807019
9: 61 0 0.05432927
10: 65 1 0.59612077
11: 68 0 0.02482168
12: 72 1 0.14582400
13: 73 0 0.02371670
14: 77 0 0.02608826
15: 87 0 0.06852409
16: 88 0 0.07473471
17: 94 0 0.07160314
18: 97 0 0.02040747
19: 104 1 0.09878789
20: 108 0 0.02421807
对于每个处理过的观察结果(即处理 = 1),我希望获得一个未处理的观察值(即处理 = 0),其得分最接近,并将所选观察值标记为不可用于其他处理过的观察值匹配。
例如,第一个处理的观察(第 10 行)将匹配到 id = 88(第 16 行),第 12 行到第 17 行,依此类推。目前我正在运行流动循环:
smpl_treated = dta[treatment == 1]
smpl_untreated = dta[treatment == 0]
n_tmp = nrow(smpl_treated)
matched_id = matrix(0, n_tmp, 1)
smpl_tmp = smpl_untreated
for (i in 1:nrow(smpl_treated)) {
x = smpl_treated[i]$score
setkey(smpl_tmp, score)
tmp = smpl_tmp[J(x), roll = "nearest"]
matched_id[i] = tmp[[1]]
smpl_tmp = smpl_tmp[id != tmp[[1]]]
}
matched_smpl = smpl_untreated[id %in% matched_id]
> matched_smpl
id treatment score
1: 87 0 0.06852409
2: 94 0 0.07160314
3: 88 0 0.07473471
有什么建议可以在 data.table 中实现或加快循环速度?使用原始的 1.2M obs 循环需要 2 多个小时。提前感谢您的帮助!
【问题讨论】:
-
假设您有以下 5 个样本:{(id = 1, treatment = 0, score = 0), (id = 2,treatment = 1, score = 0.1), (id = 3,治疗 = 1,得分 = 0.2),(id = 4,治疗 = 1,得分 = 0.3),(id = 5,治疗 = 0,得分 = 0.4)}。换句话说,您有 3 个经过处理的观察值夹在两个未处理的观察值之间。在这种情况下,什么映射到什么?
-
在我的上下文中,它不会发生。但是,如果发生这种情况,我可能应该反其道而行之——这样做的主要目的是获得经过处理和未经处理的观察结果的平衡样本。
标签: r data.table matching