R中的Complexe非equi合并

Bas*_*ien 11 r data.table

我正在尝试在两个表之间进行复杂的非equi连接.我在最后一次使用R2016的演示中受到启发(https://channel9.msdn.com/events/useR-international-R-User-conference/useR2016/Efficient-in-memory-non-equi-joins-using-datatable这使我相信它将是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
Run Code Online (Sandbox Code Playgroud)

这是dbh的树木列表.我的第二个表(下面)给出了一个通用表,它为每个树种提供了一系列dbh来对大小类或树进行分类:

gr_sp <- c("RES","RES","RES","RES","RES","RES", "DEC", "DEC", "DEC", "DEC", "DEC", "DEC")
sp <- c("SAB","SAB", "SAB", "EPN", "EPN", "EPN", "BOP", "BOP", "BOP", "PET", "PET", "PET")
dbh_min <- c(10, 16, 22, 10, 14, 20, 10, 18, 24, 10, 20, 26)
dbh_max <- c(14, 20, 30, 12, 18, 30, 16, 22, 30, 18, 24, 30)
dhb_clas <- c("s", "m", "l", "s", "m", "l", "s", "m", "l", "s", "m", "l")

dt2 <- data.table(gr_sp, sp, dbh_min, dbh_max, dhb_clas)
dt2
    gr_sp  sp dbh_min dbh_max dhb_clas
 1:   RES SAB      10      14        s
 2:   RES SAB      16      20        m
 3:   RES SAB      22      30        l
 4:   RES EPN      10      12        s
 5:   RES EPN      14      18        m
 6:   RES EPN      20      30        l
 7:   DEC BOP      10      16        s
 8:   DEC BOP      18      22        m
 9:   DEC BOP      24      30        l
10:   DEC PET      10      18        s
11:   DEC PET      20      24        m
12:   DEC PET      26      30        l
Run Code Online (Sandbox Code Playgroud)

我希望我的最终表格是两个表格的种类("sp"字段)的连接,并且在"DBH_MIN"和"DBH_MAX"所述的dhb范围内.这会使我的表看起来像:

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
Run Code Online (Sandbox Code Playgroud)

我尝试过类似的东西:

dt1[dt2, on=.(sp=sp, dbh>=dbh_min, dbh<=dbh_max)]
Run Code Online (Sandbox Code Playgroud)

这给了太多行......

谢谢你的帮助

Bas*_*ien 14

所以我非常接近.我遇到了2个问题,首先是data.table包的安装不好(数据表错误找不到函数".")导致了一个模糊的错误.

解决了这个问题后,我发现了一个发现:

dt1[dt2, on=.(sp=sp, dbh>=dbh_min, dbh<=dbh_max), nomatch=0]
Run Code Online (Sandbox Code Playgroud)

用一个糟糕的dbh列给了我想要的东西.使用以下命令反转命令:

dt2[dt1, on=.(sp=sp, dbh_min<=dbh, dbh_max>=dbh)]
Run Code Online (Sandbox Code Playgroud)

用一个无用的额外列修复了问题.

  • .使用第一种方式,可以列举你想要的列,使用`X*`和`我*`前缀:`DT1 [DT2,ON =(SP,胸径> = dbh_min,胸径<= dbh_max). (sp,dbh = x.dbh,gr_sp,dhb_clas)]` (3认同)
  • 这是一种非等同的连接方式.`dt1 [dt2,on ="sp",allow.cartesian = T] [dbh> = dbh_min&dbh <= dbh_max,-c("dbh_min","dbh_max")]`非等连接功能非常棒. ..但根据您的数据类型,另一种方法可能更快.最近我遇到了几个数百万行的情况,我会用两种方式写它,发现非等连接方法慢了2倍.就使用的内存而言,它可能略微减少. (3认同)
  • 感谢@Frank,您的评论使我更加接近完美!在通话中添加`nomatch = 0`使其变得完美! (2认同)