2015-11-02 37 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