【发布时间】:2017-11-01 02:20:32
【问题描述】:
我正在使用data.table 进行左非等连接:
OUTPUT <- DT2[DT1, on=.(DOB, FORENAME, SURNAME, POSTCODE, START_DATE <= MONTH, EXPIRY_DATE >= MONTH)]
OUTPUT 包含正确的左连接,但缺少 MONTH 列(存在于 DT1 中)除外。
这是data.table 中的错误吗?
NB:当然,START_DATE、EXPIRY_DATE 和 MONTH 是相同的 YYYY-MM-DD、IDate 格式。根据这些非 equi 标准,连接的结果是正确的。只是缺少该列,我需要在进一步的工作中使用它。
编辑 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 日,结束日期为 12 月 31 日!预期的输出是应该的。但实际输出是 1 月 1 日。
【问题讨论】:
-
提供reproducible example 总是好的。就目前的问题而言,人们很难看出哪里出了问题。
-
除了 MONTH 列(DT1 中存在)缺失之外,是什么意思?
OUTPUT中是否缺少它?如果这是您的问题:这是正常行为,因为您正在加入它。因此,OUTPUT将有START_DATE和EXPIRY_DATE,但没有MONTH,因为它是与其他两个进行比较的。 -
@Jaap:是的,这正是正在发生的事情。但是,
OUTPUT仍然包含DOB、FORENAME、SURNAME、POSTCODE,并且这些列也正在加入。是否有调整以保留MONTH列? -
不确定,但您可以尝试
OUTPUT <- DT2[DT1, on=.(DOB, FORENAME, SURNAME, POSTCODE, START_DATE <= MONTH, EXPIRY_DATE >= MONTH), MONTH := i.MONTH]。但正如我在之前的评论中所说:没有reproducible example 很难测试。
标签: r join data.table left-join