非等值内部联接(nomatch = 0L)是否应该是双向的?

时间:2019-07-12 01:54:51

标签: r data.table

在进行非等价内部联接时,X [Y]和Y [X]的顺序是否重要?我觉得它不应该。

library(data.table) #data.table_1.12.2
dt1 <- data.table(ID=LETTERS[1:4], TIME=2L:5L)
cols1 <- names(dt1)
dt2 <- data.table(ID=c("A", "B"), START=c(1L, 20L), END=c(3L, 30L))
cols2 <- names(dt2)

> dt1
   ID TIME
1:  A    2
2:  B    3
3:  C    4
4:  D    5

> dt2
   ID START END
1:  A     1   3
2:  B    20  30

我正在尝试过滤dt1中的行,以便1)ID匹配和2)dt1 $ TIME位于dt2 $ START和dt2 $ END之间。所需的输出:

   ID TIME
1:  A    2

由于我希望从dt1获得行,因此我开始在dt1中将i用作data.table[,但是我从dt2获取列或遇到错误:

#no error but using x. values
dt2[dt1, on=.(ID, START<TIME, END>TIME), nomatch=0L]

#error for the rest 
dt2[dt1, on=.(ID, START<TIME, END>TIME), nomatch=0L, mget(paste0("i.", cols1))]
dt2[dt1, on=.(ID, START<TIME, END>TIME), nomatch=0L, .SD]
dt2[dt1, on=.(ID, START<TIME, END>TIME), nomatch=0L, .(START)]

错误消息:

  

[.data.table(dt2,dt1,on =。(ID,START TIME),的错误:找不到列:START

所以我必须使用dt2作为i作为解决方法:

#need to type out all the columns:
dt1[dt2, on=.(ID, TIME>START, TIME<END), nomatch=0L, .(ID, TIME=x.TIME)]
#using setNames
dt1[dt2, on=.(ID, TIME>START, TIME<END), nomatch=0L, 
    setNames(mget(paste0("x.", cols1)), cols1)]

这是我误会的一个简单例子吗?

参考文献:

1 个答案:

答案 0 :(得分:1)

  

我正在尝试过滤dt1中的行,以便1)ID匹配和2)dt1 $ TIME位于dt2 $ START和dt2 $ END之间。

这听起来像半联接:Perform a semi-join with data.table

dt1[
  dt1[dt2, on=.(ID, TIME >= START, TIME <= END), nomatch=0, which=TRUE]
]

#    ID TIME
# 1:  A    2

如果dt2的多行可能与dt1的行匹配,则可以按照链接的答案,将“ which”输出包装在unique()中。

有几个链接的功能请求,它们提供了一种更方便的方法:https://github.com/Rdatatable/data.table/issues/2158