R中的Complexe非等合并

R中的Complexe非等合并,r,data.table,R,Data.table,我正在尝试在两个表之间进行复杂的非相等联接。上一次useR2016()中的一次演示激发了我的灵感,使我相信这将是data.table的合适任务。我的表1看起来像: library(data.table) sp <- c("SAB","SAB","SAB","SAB","EPN","EPN","BOP","BOP","BOP","BOP","BOP","PET","PET","PET") dbh <- c(10,12,16,22,12,16,10,12,14,20,26,12,16,1

我正在尝试在两个表之间进行复杂的非相等联接。上一次useR2016()中的一次演示激发了我的灵感,使我相信这将是data.table的合适任务。我的表1看起来像:

library(data.table)
sp <- c("SAB","SAB","SAB","SAB","EPN","EPN","BOP","BOP","BOP","BOP","BOP","PET","PET","PET")
dbh <- c(10,12,16,22,12,16,10,12,14,20,26,12,16,18)
dt1 <- data.table(sp,dbh)
dt1
     sp dbh
 1: SAB  10
 2: SAB  12
 3: SAB  16
 4: SAB  22
 5: EPN  12
 6: EPN  16
 7: BOP  10
 8: BOP  12
 9: BOP  14
10: BOP  20
11: BOP  26
12: PET  12
13: PET  16
14: PET  18
data.table(dt1, gr_sp = c("RES","RES","RES","RES","RES","RES","DEC","DEC","DEC","DEC","DEC","DEC","DEC","DEC"), dhb_clas = c("s","s","m","l","s","m","s","s","s","m","l","s","s","s"))
     sp dbh gr_sp dhb_clas
 1: SAB  10   RES        s
 2: SAB  12   RES        s
 3: SAB  16   RES        m
 4: SAB  22   RES        l
 5: EPN  12   RES        s
 6: EPN  16   RES        m
 7: BOP  10   DEC        s
 8: BOP  12   DEC        s
 9: BOP  14   DEC        s
10: BOP  20   DEC        m
11: BOP  26   DEC        l
12: PET  12   DEC        s
13: PET  16   DEC        s
14: PET  18   DEC        s
我试过这样的方法:

dt1[dt2, on=.(sp=sp, dbh>=dbh_min, dbh<=dbh_max)]

dt1[dt2,on=。(sp=sp,dbh>=dbh_min,dbh所以我非常接近。我有两个问题,首先是data.table包()的错误安装导致了一个模糊的错误

在解决了这个问题后,我走近一点,发现:

dt1[dt2, on=.(sp=sp, dbh>=dbh_min, dbh<=dbh_max), nomatch=0]
dt1[dt2,on=(sp=sp,dbh>=dbh_min,dbh对于像这样的“中间”连接,也可以使用
数据。table::foverlaps
,它连接两个
数据。table
在重叠的范围上,而不是使用非相等连接

以相同的示例为例,下面的代码将生成所需的结果

# foverlap tests the overlap of two ranges.  Create a second column,
# dbh2, as the end point of the range.
dt1[, dbh2 := dbh]

# foverlap requires the second argument to be keyed
setkey(dt1, sp, dbh, dbh2)

# find rows where dbh falls between dbh_min and dbh_max, and drop unnecessary
# columns afterwards
foverlaps(dt2, dt1, by.x = c("sp", "dbh_min", "dbh_max"), by.y = key(dt1),
          nomatch = 0)[
  ,
  -c("dbh2", "dbh_min", "dbh_max")
]

#  sp dbh gr_sp dhb_clas
#  1: SAB  10   RES        s
#  2: SAB  12   RES        s
#  3: SAB  16   RES        m
#  4: SAB  22   RES        l
#  5: EPN  12   RES        s
#  6: EPN  16   RES        m
#  7: BOP  10   DEC        s
#  8: BOP  12   DEC        s
#  9: BOP  14   DEC        s
# 10: BOP  20   DEC        m
# 11: BOP  26   DEC        l
# 12: PET  12   DEC        s
# 13: PET  16   DEC        s
# 14: PET  18   DEC        s

使用第一种方法,您可以使用
x.*
i.*
前缀来枚举所需的列:
dt1[dt2,on=。(sp,dbh>=dbh_min,dbh请遵循@Frank关于使用
x.
前缀的建议。这对于非等联接特别有用,因为与基数R一致,您在联接中使用了重命名列。这在中进行了讨论。感谢@Frank,您的评论让我更接近完美!将
nomatch=0
添加到您的调用中使其变得完美!这里有一种非等连接的方法来做同样的事情。
dt1[dt2,on=“sp”,allow.cartesian=T][dbh>=dbh\u min&dbht这是一个很好的非等联接线程,尽管有点旧。@ironv如果两个DTs之间没有一个公共列,如何避免使用非等联接。在本例中,有一个公共列
sp
。这是有意义的。
dt2[dt1, on=.(sp=sp, dbh_min<=dbh, dbh_max>=dbh)]
# foverlap tests the overlap of two ranges.  Create a second column,
# dbh2, as the end point of the range.
dt1[, dbh2 := dbh]

# foverlap requires the second argument to be keyed
setkey(dt1, sp, dbh, dbh2)

# find rows where dbh falls between dbh_min and dbh_max, and drop unnecessary
# columns afterwards
foverlaps(dt2, dt1, by.x = c("sp", "dbh_min", "dbh_max"), by.y = key(dt1),
          nomatch = 0)[
  ,
  -c("dbh2", "dbh_min", "dbh_max")
]

#  sp dbh gr_sp dhb_clas
#  1: SAB  10   RES        s
#  2: SAB  12   RES        s
#  3: SAB  16   RES        m
#  4: SAB  22   RES        l
#  5: EPN  12   RES        s
#  6: EPN  16   RES        m
#  7: BOP  10   DEC        s
#  8: BOP  12   DEC        s
#  9: BOP  14   DEC        s
# 10: BOP  20   DEC        m
# 11: BOP  26   DEC        l
# 12: PET  12   DEC        s
# 13: PET  16   DEC        s
# 14: PET  18   DEC        s