R 通过两个变量和最近的第三个变量合并data.table

R 通过两个变量和最近的第三个变量合并data.table,r,merge,dataframe,data.table,R,Merge,Dataframe,Data.table,我想对data.tables执行一个操作,目前我可以成功地对data.frames执行该操作。本质上,它是两个data.frames的合并函数,用于为许多匹配变量中的一个在df2中为df1查找最接近的匹配。下面是代码 我希望在data.tables中执行此操作,因为我的data.frames非常大,如果我尝试在完整数据上完成此操作,当前设置将崩溃。Data.table可能允许我在整个集合上直接执行此操作,但如果不是,我发现Data.table在使用多个数据子集时更易于使用 我正在通过变量MM和v

我想对data.tables执行一个操作,目前我可以成功地对data.frames执行该操作。本质上,它是两个data.frames的合并函数,用于为许多匹配变量中的一个在df2中为df1查找最接近的匹配。下面是代码

我希望在data.tables中执行此操作,因为我的data.frames非常大,如果我尝试在完整数据上完成此操作,当前设置将崩溃。Data.table可能允许我在整个集合上直接执行此操作,但如果不是,我发现Data.table在使用多个数据子集时更易于使用

我正在通过变量
MM
variable
(在此data.frame方法中,如果存在最接近的匹配关系,则可能会发生多对),从df2中查找与df1中
状态
最接近的
Id
(及其相应的
)(例如,同时存在正1和负1的值)).当使用data.frames时,我得到的解决方案如下所示
final
。我不知道如何设置data.table以获得相同的结果。我尝试了不同的键,下面是一个示例。我在代码中引用的data.frames问题中有一个using data.table,但是,我无法将其用于示例数据

# data.frame method
# used info from this thread: https://stackoverflow.com/questions/16095680
df1 <- structure(list(State = structure(c(1L, 1L, 3L, 3L, 2L, 2L, 1L, 
1L, 1L), .Label = c("AK", "CO", "MS"), class = "factor"), MM = c(1L, 
2L, 1L, 2L, 3L, 4L, 3L, 4L, 2L), variable = structure(c(1L, 1L, 
1L, 1L, 2L, 2L, 2L, 2L, 2L), .Label = c("TMN", "TMX"), class = "factor"), 
    value = c(1L, 2L, 3L, 4L, 2L, 3L, 5L, 6L, 7L)), .Names = c("State", 
"MM", "variable", "value"), class = "data.frame", row.names = c(NA, 
-9L))
df2 <- structure(list(Id = c(1L, 2L, 3L, 1L, 2L, 3L, 5L, 6L, 7L, 5L, 
6L, 7L, 8L), MM = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 
4L, 5L), variable = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L), .Label = c("TMN", "TMX"), class = "factor"), 
    value = c(1, 2, 3, 2, 3, 4, 2, 3, 5.5, 6.5, 3.5, 2.5, 8)), .Names = c("Id", 
"MM", "variable", "value"), class = "data.frame", row.names = c(NA, 
-13L))

#Find rows that match by x and y
res <- merge(df1, df2, by = c("MM", "variable"), all.x = TRUE)

res$dif <- abs(res$value.x - res$value.y)

#Find rows that need to be merged
res1 <- merge(aggregate(dif ~ MM + variable, data = res, FUN = min), res)

#Finally merge the result back into df1
final <- merge(df1, res1[res1$dif <= 1, c("MM", "variable", "State", "Id", "value.y")], all.x = TRUE)

### one Data.table attempts
# create data.tables with the same key columns
keycols1 = c("MM", "variable", "value")
df1t <- data.table(df1, key = keycols1)
df2t <- data.table(df2, key = key(df1t))
setkey(df1t, value)
setkey(df2t, value)
test.final <- df2t[df1t, roll='nearest', allow.cartesian=TRUE]
#data.frame方法
#已使用此线程的信息:https://stackoverflow.com/questions/16095680

df1不确定这是否是实现所需的最佳方法,但这里有一种方法与数据帧类似,只使用data.tables:

dt1 <- data.table(df1)
dt2 <- data.table(df2)
res <- merge(dt1, dt2, by = c("MM", "variable"), all.x = TRUE, allow.cartesian=TRUE)
final_dt <- res[, .SD[abs(value.x - value.y) == min(abs(value.x - value.y))], by=c("State", "MM", "variable")]

dt1在您的示例中,数据帧
final
中的结果似乎与您希望获得的内容的描述不匹配。例如,为什么组合(state=AK,variable=TMN,MM=1)在
final
中生成两行,它不应该只生成一个最匹配的Id吗?@YT谢谢,缺少
“state”
在data.frame'final'的代码中
final\u dt Yes,如果您添加by子句,即它转换为:对于每个状态,MM,变量组合,返回res中的行子集,其中value.x-value.y等于最小值(后一位确保,如果存在多个等于最小值的差异,则每个分组可以获得多个命中)。