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

时间:2015-08-31 17:02:31

标签: sql r data.table

可能是一个天真的问题,但考虑到以下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

我希望我对数据和试验不太模糊。 如果这是一个编码问题,那么我该如何解决呢?

1 个答案:

答案 0 :(得分:2)

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

如果您可以提供示例数据,则可以更轻松地进行跟踪。另外一定要检查最新的开发版本,因为已经修复了一些错误。您可以在Installation wiki page中找到安装说明。

使用最新的dev时,您可以使用以下方式在数据表上设置密钥时加入:

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

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