我正在使用data.table
进行左非等连接:
OUTPUT <- DT2[DT1, on=.(DOB, FORENAME, SURNAME, POSTCODE, START_DATE <= MONTH, EXPIRY_DATE >= MONTH)]
OUTPUT
包含正确的左连接,但MONTH
列(存在于DT1中)缺失。
这是data.table
中的错误吗?
注意:当然,START_DATE
,EXPIRY_DATE
和MONTH
采用相同的YYYY-MM-DD,IDate格式。基于这些非等标准,连接的结果是正确的。只是该列缺失,我需要在进一步的工作中使用它。
编辑1 :简化的可重现示例
DT1 <- structure(list(ID = c(1, 2, 3), FORENAME = c("JOHN", "JACK",
"ROB"), SURNAME = c("JOHNSON", "JACKSON", "ROBINSON"), MONTH = structure(c(16953L,
16953L, 16953L), class = c("IDate", "Date"))), .Names = c("ID",
"FORENAME", "SURNAME", "MONTH"), row.names = c(NA, -3L), class = c("data.table",
"data.frame"))
DT2 <- structure(list(CERT_NUMBER = 999, FORENAME = "JOHN", SURNAME = "JOHNSON",
START_DATE = structure(16801L, class = c("IDate", "Date")),
EXPIRY_DATE = structure(17166L, class = c("IDate", "Date"
))), .Names = c("CERT_NUMBER", "FORENAME", "SURNAME", "START_DATE",
"EXPIRY_DATE"), row.names = c(NA, -1L), class = c("data.table",
"data.frame"))
OUTPUT <- DT2[DT1, on=.(FORENAME, SURNAME, START_DATE <= MONTH, EXPIRY_DATE >= MONTH)]
> OUTPUT
CERT_NUMBER FORENAME SURNAME START_DATE EXPIRY_DATE ID
1: 999 JOHN JOHNSON 2016-06-01 2016-06-01 1
2: NA JACK JACKSON 2016-06-01 2016-06-01 2
3: NA ROB ROBINSON 2016-06-01 2016-06-01 3
FORENAME
和SURNAME
已加入并显示在输出中。MONTH
也是(非equi)加入,并且不在输出中。为什么这是预期的行为?
即使是预期的行为,在我的情况下也没有用,因为我需要保留MONTH
以进行进一步的数据操作。
我的预期输出将是同一个表,但保留MONTH
列,因为它在DT1中。毕竟,我对左连接的期望是从左表(DT1)和所有列保留每个行和列,并且只从右表(DT2)添加匹配的行。
CERT_NUMBER FORENAME SURNAME START_DATE EXPIRY_DATE ID MONTH
1: 999 JOHN JOHNSON 2016-01-01 2016-12-31 1 2016-06-01
2: NA JACK JACKSON <NA> <NA> 2 2016-06-01
3: NA ROB ROBINSON <NA> <NA> 3 2016-06-01
编辑2 :显然在我的代码生成的输出中,START和END日期也是错误的!只有1人拥有证书,其开始日期为1月1日,结束日期为31日至12月!预期的产出应该是应有的。但实际输出完成了1 - 1月的所有事情。
答案 0 :(得分:18)
在data.table中,x[i]
形式的联接传统上使用i
中的值,但使用x
中的列名。虽然这与返回两者的SQL不同,但是这个默认值对于 equi 连接很有意义,因为我们对来自i
的所有行感兴趣,如果它们匹配那么两个data.tables无论如何都要相等值,如果他们不这样做,我们就需要保留i
中不匹配的值。
但是对于非equi 连接,由于值可能与完全匹配,即可能落在某个范围内,可能会出现我们必须返回的情况输出类似于SQL(或识别此类情况并返回用户期望的结果,类似于equi连接的情况)。这还没有完成,但我现在已经为它设置了一个条款,即使用x.
前缀明确引用列。我同意,这不方便。希望这很快就会自动完成。
以下是使用x.
前缀获取结果的方法。
ans <- DT2[DT1, .(CERT_NUMBER, FORENAME, SURNAME, x.START_DATE, x.EXPIRY_DATE, ID, MONTH),
on=.(FORENAME, SURNAME, START_DATE <= MONTH, EXPIRY_DATE >= MONTH)]
IIRC还有一个关于GITHub项目页面的问题。