2015-12-17 9 views
11

मैं left_join से अधिक डेटा फ्रेम करना चाहते हैं:dplyr का उपयोग कर एकाधिक डेटा फ्रेम में कैसे शामिल हों?

dfs <- list(
    df1 = data.frame(a = 1:3, b = c("a", "b", "c")), 
    df2 = data.frame(c = 4:6, b = c("a", "c", "d")), 
    df3 = data.frame(d = 7:9, b = c("b", "c", "e")) 
) 
Reduce(left_join, dfs) 
# a b c d 
# 1 1 a 4 NA 
# 2 2 b NA 7 
# 3 3 c 5 8 

यह काम करता है क्योंकि वे सभी एक ही b स्तंभ है, लेकिन Reduce मुझे अतिरिक्त तर्क है कि मैं left_join को पारित कर सकते हैं निर्दिष्ट नहीं देता। क्या इस तरह के लिए कुछ काम है?

dfs <- list(
    df1 = data.frame(a = 1:3, b = c("a", "b", "c")), 
    df2 = data.frame(c = 4:6, d = c("a", "c", "d")), 
    df3 = data.frame(d = 7:9, b = c("b", "c", "e")) 
) 

अद्यतन

काम करता है इस तरह की: Reduce(function(...) left_join(..., by = c("b" = "d")), dfs) लेकिन जब by एक तत्व की तुलना में अधिक है, यह इस त्रुटि देता है: Error: cannot join on columns 'b' x 'd': index out of bounds

+3

(डीएफएस समारोह (...) left_join (..., यहाँ अन्य args),) आप 'कम नहीं कर सकते' ? –

+0

मैंने इसके बारे में सोचा नहीं था। हाँ मैं कर सकता हूँ! इसे अपने उत्तर – nachocab

+0

हम्म के रूप में लिखने के लिए स्वतंत्र महसूस करें, वास्तव में, यह तोड़ता है यदि 'by' में एक से अधिक तत्व हैं। अद्यतन – nachocab

उत्तर

3

मुझे बहुत देर हो चुकी है मुझे पता है .... आज मुझे अनुत्तरित प्रश्न अनुभाग में पेश किया गया है। परेशान करने के लिए क्षमा करें।

merge() का उपयोग left_join()

dfs <- list(
       df1 = data.frame(b = c("a", "b", "c"), a = 1:3), 
       df2 = data.frame(d = c("a", "c", "d"), c = 4:6), 
       df3 = data.frame(b = c("b", "c", "e"), d = 7:9) 
     ) 

func <- function(...){ 
    df1 = list(...)[[1]] 
    df2 = list(...)[[2]] 
    col1 = colnames(df1)[1] 
    col2 = colnames(df2)[1] 
    xxx = left_join(..., by = setNames(col2,col1)) 
    return(xxx) 
} 
Reduce(func, dfs) 
# b a c d 
#1 a 1 4 NA 
#2 b 2 NA 7 
#3 c 3 5 8 

का उपयोग करना:

func <- function(...){ 
    df1 = list(...)[[1]] 
    df2 = list(...)[[2]] 
    col1 = colnames(df1)[1] 
    col2 = colnames(df2)[1] 
    xxx=merge(..., by.x = col1, by.y = col2, , all.x = T) 
    return(xxx) 
} 

Reduce(func, dfs) 
# b a c d 
#1 a 1 4 NA 
#2 b 2 NA 7 
#3 c 3 5 8 
+0

पर ध्यान दें कि मुझे पहले कॉलम के रूप में "कुंजी" चर रखना था, क्योंकि विलय के बाद वे डेटाफ्रेम में स्वचालित रूप से पहले कॉलम बन गए –

4

क्या आप के लिए यह काम करता है?

jnd.tbl <- df1 %>% 
    left_join(df2, by='b') %>% 
    left_join(df3, by='d') 
+5

बहुत अच्छी तरह से सामान्यीकृत नहीं है (जो प्रश्न का बिंदु प्रतीत होता है)। – Gregor

+1

यह सबसे अच्छा समाधान प्रतीत होता है। यह वास्तव में काफी अच्छा है, वास्तव में: यदि आप किसी अन्य तालिका में शामिल होना चाहते हैं, तो बस पाइपलाइन पर एक और पंक्ति जोड़ें। कोड एक एसक्यूएल एकाधिक-जॉइन क्वेरी से बहुत अलग नहीं दिख रहा है। –

+0

@ हांगोई लेकिन द्वारा = चर सही बदलता है? कृपया इस उत्तर को –

संबंधित मुद्दे