使用 data.tables 的内部连接与使用复合字符键的 SQL 的内部连接(编码问题?)

Inner join with data.tables vs. inner join in SQL with composite character key (encoding issue?)

也许是个幼稚的问题,但给出以下 SQL 查询:

SELECT *
FROM DT1 
INNER JOIN DT2 
  ON (DT1.col1 = DT2.col1) 
  AND (DT1.col2 = DT2.col2) 
  AND (DT1.col3 = DT2.col3);

它应该等同于R中的以下内容,还是?

DT1[DT2, nomatch=0]

按键设置如下:

setkey(DT1, col1, col2, col3)
setkey(DT2, col1, col2, col3)

什么可以确定我得到不同的结果?

更新: 正如@jangorecki 所建议的那样,可能存在编码问题。 无论如何,我会尝试提供数据。我对大数据集深表歉意,但很难检测出导致问题的原因并提出一个最小的例子。

library(data.table)
# the files are in this repository: https://github.com/ValStef/ConsvStat
DT1 <-  fread("https://raw.githubusercontent.com/ValStef/ConsvStat/master/DT1.txt")
# on my PC I get no error with fread for DT1 but seems that when reading from github I get some errors (otherwise try to download the DT1.zip file from the repository)
DT2 <-  fread("https://raw.githubusercontent.com/ValStef/ConsvStat/master/DT2.txt")
# note that file DT1 is comma separated and the DT2 is tab separated (but fread should manage
# Initially I just neglected the encoding warnings

# set the key for each data table
setkey(DT1, country, region, habitatcode)
setkey(DT2, country, region, habitatcode)

# perform the join
DT.inner.join <- DT2[DT1, nomatch=0]
# it works, except that I get 3069 rows

-

# but running the SQL statement in the original MS Access mdb file returns 3117 rows 
# which is the number of rows of DT1, which is the expected result
SELECT DT1.country, DT1.region, DT1.habitatcode, DT2.habitatgroup
FROM DT1 
INNER JOIN DT2 
ON DT1.country = DT2.country
AND DT1.region = DT2.region
AND DT1.habitatcode = DT2.habitatcode

您还可以在上述存储库中找到 SQL 查询结果

SQL_output <-  fread("https://raw.githubusercontent.com/ValStef/ConsvStat/master/Query1.csv")

我尝试遵循 https://github.com/Rdatatable/data.table/issues/685 的建议(加入具有不同编码的字符列)。我 运行 @stefanfritsch setencoding() 和 setencodingv() 提出的功能,如:

setencoding(DT1, country, region, habitatcode)
setencoding(DT2, country, region, habitatcode)
# after which I set the keys again and I run the join 

但我遇到了同样的问题。

merge() 函数(如预期的那样)不会带来任何变化:

DT.inner.join2 <- merge(DT1, DT2, all=FALSE) # returns also 3069 rows

我希望我对数据和试验没有太含糊。 如果这是编码问题,我该如何解决?

是的,应该。
您得到不同结果的原因可能来自:

如果您可以提供示例数据,跟踪起来会容易得多。还要确保检查最新的开发版本,因为那里已经修复了一些错误。您可以在 Installation wiki page 中找到安装说明。

当使用最新的开发者时请注意,您可以使用以下方式加入而无需在数据表上设置键:

DT1[DT2, on=c("col1", "col2", "col3"), nomatch=0]

如果上述 none 个原因有帮助,您可以在 data.table github 上填写问题,但如果没有任何数据样本,可能无法调试。在填写错误报告之前,请务必检查 1.9.5。