2015-11-02 27 views
0

我想使用sqldf包连接两个数据帧。用sqldf连接两个数据帧导致NA列

这些是我的两个dataframes的再现的例子:

a <- c(1,2,3,4,5) 
b <- c(1,2,3,4,5) 
c <- c(1,2,3,4,5) 
d <- c(1,2,3,4,5) 
e <- c(1,2,3,4,5) 

dataframe1 <- data.frame(a,b,c,d,e) 

a <- c(NA,NA,NA,NA,5) 
b <- c(NA,NA,NA,4,NA) 
c <- c(NA,NA,3,NA,NA) 
d <- c(NA,2,NA,NA,NA) 
e <- c(1,NA,NA,NA,NA) 
f <- c(1,2,3,4,5) 

dataframe2 <- data.frame(a,b,c,d,e,f) 

这是对dataframes联接可再现例如:

final_data <- sqldf("SELECT * 
        FROM dataframe1 
        LEFT OUTER JOIN dataframe2 USING(a,b,c,d,e)") 

其经由引入final_data的产生的F列加入充满了新生。为什么?理想的f列将具有dataframe2中存在的a,b,c,d和e的相应值。我怎么能解决这个问题?

+0

这两个数据框之间没有匹配的行,所以结果是'dataframe1',新'f'列中的值全部为NULL(SQL中为NULL,R中为NA)。如果你需要'f'列中的值,你至少需要一行数据帧之间的所有'a,b,c,d,e'匹配。 – Gregor

+0

有没有办法在我的连接中排除NAs,并且只在dataframe2的每一行中插入对应于共享值的值? R中的merge()函数使用参数“incompatibles = NA”来实现,但这只适用于加入一列并且我加入5. – jgozal

+0

也许我可以在我的连接中指定加入公共列(a或b或c或d或e),以便它只在与其中一个值匹配时才加入。我怎么能把它在SQL? – jgozal

回答

2

如果你想OR标准,相应的SQL是

SELECT * 
FROM dataframe1 d1 
LEFT OUTER JOIN dataframe2 d2 
ON (
    d1.a = d2.a 
    OR d1.b = d2.b 
    OR d1.c = d2.c 
    OR d1.d = d2.d 
    OR d1.e = d2.e 
) 

由于从df1列值不一定等于来自df2,你从他们每个人得到一份拷贝。如果你只想保留来自df1以及来自df2f的值,那么做到这一点:

SELECT d1.*, d2.f 
FROM dataframe1 d1 
LEFT OUTER JOIN dataframe2 d2 
ON (
    d1.a = d2.a 
    OR d1.b = d2.b 
    OR d1.c = d2.c 
    OR d1.d = d2.d 
    OR d1.e = d2.e 
) 

将R加入我知道(mergeplyr::joindplyr::left_join)函数都需要所有列在加入是平等的,尽管你可以很容易地将一个自定义函数一起加入,然后结果。

+0

这个工程。谢谢格雷戈尔。我不知道该库接受完全原生的SQL。 – jgozal

+1

它真正创建一个SQL数据库,导入你使用的任何数据帧,执行你的SQL,并将结果导回到R. – Gregor

+0

有趣 - 这是一个不同的问题,但是你知道是否有任何r包导入数据帧到sql数据库为表? – jgozal