我有来自两个不同提供商的两个数据集,记录不同ID下的学生成绩。一些学生出现在两个数据集中。
DT1 = data.table(id = 1:6,
math = c(6.55, 7.39, 5.89, 9.70, 4.77, 5.30),
engl = c(8.55, 8.83, 9.20, 9.10, 4.32, 8.17),
hist = c(7.37, 3.39, 8.11, 2.10, 1.58, 6.65),
geog = c(10.0, 7.63, 2.37, 8.44, 6.35, 7.10))
DT2 = data.table(id = LETTERS[1:6],
math2 = c(6.55, 7.39, 5.88, 9.70, 4.17, 9.70),
engl2 = c(8.53, 6.83, 9.19, 9.10, 4.22, 9.10),
hist2 = c(7.39, 2.39, 8.12, 2.10, 1.58, 2.10),
geog2 = c(10.0, 7.43, 2.38, 8.44, 6.45, 8.44))
我想合并它们两个,以便了解ID通信。要做到这一点,我必须匹配成绩。问题是不同的数据集有不同的舍入,因此,为了在两个数据集上找到学生,我必须匹配最接近的成绩。
截至目前,我正在做以下事情
subj = names(DT2)[-1] # get the subjects
#create interval on the grades, so I can run the non-equi join
DT2[, paste0(subj, "_min") := lapply(.SD, function(x) x - 0.02), .SDcols = subj]
DT2[, paste0(subj, "_max") := lapply(.SD, function(x) x + 0.02), .SDcols = subj]
DTm = DT1[DT2, on = .(math >= math2_min, math <= math2_max,
engl >= engl2_min, engl <= engl2_max), nomatch = 0]
总之,我创建了等级+/- 0.02的间隔并进行了非等联接,这得到了正确的答案(在上面的示例中,我在DT2中有重复,这很好)。
但是,我想在不提供间隔的情况下这样做,因为我不知道要提供哪个间隔。
有没有办法进行与最接近值匹配的非equi连接?当我说最接近的意思是,找到math
中math2
的最接近值,然后找到engl
中engl2
的最接近值。如果两个值来自同一个观察值,那么它是一个匹配,如果没有,那么就没有匹配。
答案 0 :(得分:4)
这似乎满足您对最接近的定义,但与您的示例结果不符:
DT1[DT2, on = .(math = math2), roll = 'nearest', math.id := i.id][
DT2, on = .(engl = engl2), roll = 'nearest', engl.id := i.id][
math.id == engl.id]
# id math engl hist geog math.id engl.id
#1: 1 6.55 8.55 7.37 10.00 A A
#2: 3 5.89 9.20 8.11 2.37 C C
#3: 4 9.70 9.10 2.10 8.44 F F
#4: 5 4.77 4.32 1.58 6.35 E E