r - R 数据表中最近的 "n"滚动连接

标签 r join data.table

data.table ,我们可以使用 roll = "nearest" 将一个数据集中的值与另一个数据集中的最近值连接起来。 .一些示例数据:

dt1 <- data.table(x = c(15,101), id1 = c("x", "y"))
dt2 <- data.table(x = c(10,50,100,200), id2 = c("a","b","c","d"))
使用 roll = "nearest" ,我可以将 'dt1' 中的每个 'x' 与最近的 dt2 中的 'x' 连接起来:
dt2[dt1, roll = "nearest", on = "x"]
#     x  id2 id1
# 1: 15    a   x
# 2: 101   c   y
例如。为 x = 15在“dt1”中,最近的 x 'dt2' 中的值为 x = 10 ,我们得到相应的“id2”,即 "a" .
但是,如果不是获得一个最近的值,而是想要获得 n 个最近的值呢?例如,如果我想要 2 个最接近的 x 值,结果将是:
     x id2 id1  roll
1:  15   a   x   nr1
2:  15   b   x   nr2
3: 101   c   y   nr1
4: 101   b   y   nr2
(“nr”代表“最近的”)
我想要一种可以应用于任何“n”的通用方法(例如 2 个最近的点、3 个最近的点等)。

编辑
我想知道是否也可以将此应用于多列连接,其中连接将在前一列上匹配,然后在最后一个连接列上获得最近的列。例如:
dt1 <- data.table(group=c(1,2), x=(c(15,101)), id1=c("x","y"))
dt2 <- data.table(group=c(1,2,2,3), x=c(10,50,100,200),id2=c("a","b","c","d"))
如果我加入 on=c("group","x") ,连接将首先匹配“组”,然后在“x”上获得最接近的,所以我希望结果是这样的:
     x  group id2 id1  roll
1:  15      1   a   x   nr1
2: 101      2   c   y   nr1
3: 101      2   b   y   nr2

最佳答案

这是一些非常原始的东西(我们逐行进行):

n <- 2L
sen <- 1L:n
for (i in 1:nrow(dt1)) {
  set(dt1, i, j = "nearest", list(which(frank(abs(dt1$x[i] - dt2$x)) %in% sen)))
}
dt1[, .(id1, nearest = unlist(nearest)), by = x
    ][, id2 := dt2$id2[nearest]
      ][, roll := paste0("nr", frank(abs(dt2$x[nearest] - x))), by = x][]

#      x id1 nearest id2 roll
# 1:  15   x       1   a  nr1
# 2:  15   x       2   b  nr2
# 3: 101   y       2   b  nr2
# 4: 101   y       3   c  nr1
干净一点:
dt1[, 
    {
      nrank <- frank(abs(x - dt2$x), ties.method="first")
      nearest <- which(nrank %in% sen)
      .(x = x, id2 = dt2$id2[nearest], roll = paste0("nr", nrank[nearest]))
    }, 
    by = id1] # assumes unique ids.
数据:
dt1 <- data.table(x = c(15, 101), id1 = c("x", "y"))
dt2 <- data.table(x = c(10, 50, 100, 200), id2 = c("a", "b", "c", "d"))

编辑 (根据OP的建议/编写)
使用多个键加入:
dt1[, 
    {
      g <- group
      dt_tmp <- dt2[dt2$group == g]
      nrank <- frank(abs(x - dt_tmp$x), ties.method="first")
      nearest <- which(nrank %in% sen)
      .(x = x, id2 = dt_tmp$id2[nearest], roll = paste0("nr", nrank[nearest]))
    }, 
    by = id1]

关于r - R 数据表中最近的 "n"滚动连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62760320/

相关文章:

r - 如何拆分但忽略R中引用字符串中的分隔符?

r - 使用循环顺序更新 data.table 列

r - 将stat_smooth约束到特定范围

r - 如何检查一个单词是否是回文?

php - mySQL JOIN 三个表 - 电子商务项目、 View 和销售

java - java中无法正确连接两个表;数据传输组织

r - 频率表和 r 中的多个变量分组

r - 在 R 中生成 XML 文档

带有 .combine=rbindlist 的 R foreach

c# - 当不同类型的列表的属性值相等时,从列表中排除的 Linq 查询?