2015-12-17 14 views
11

Chcę left_join wielu ramek danych:Jak połączyć wiele ramek danych za pomocą 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 

To działa, ponieważ wszystkie one mają taką samą b kolumnę, ale Reduce nie pozwala mi określić dodatkowe argumenty, które można przekazać do left_join. Czy istnieje coś takiego do wykonania?

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")) 
) 

Aktualizacja

Ten rodzaj prac: Reduce(function(...) left_join(..., by = c("b" = "d")), dfs)by ale gdy jest więcej niż jeden element, to daje ten błąd: Error: cannot join on columns 'b' x 'd': index out of bounds

+3

Czy nie robisz 'Reduce (function (...) (..., left_join inne argumenty tutaj), DFS)' ? –

+0

Nie pomyślałem o tym. Tak, mogę! Zapraszam do napisania go jako odpowiedź – nachocab

+0

Hmm, faktycznie, to się zepsuje, jeśli 'by' ma więcej niż jeden element. Zobacz aktualizację – nachocab

Odpowiedz

3

Było już za późno, wiem ... dziś zapoznałem się z sekcją pytań bez odpowiedzi. Przepraszam, że przeszkadzam.

Korzystanie 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 

Korzystanie merge():

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

, aby zauważyć: Musiałem zachować zmienne "klucz" jako pierwszą kolumnę, ponieważ po połączeniu automatycznie stają się one pierwszymi kolumnami w ramce danych –

4

będzie to praca dla Ciebie?

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

Nie generalizuje bardzo dobrze (co wydaje się być punktem pytania). – Gregor

+1

To wydaje się być najlepszym rozwiązaniem. Generuje to całkiem dobrze: jeśli chcesz dołączyć do innej tabeli, po prostu dodaj jeszcze jedną linię do potoku. Kod zakończyłby się wyglądem nie różniącym się zbytnio od zapytania wielokrotnego łączenia SQL. –

+0

@HongOoi, ale zmienna by = zmienia się w prawo? proszę sprawdzić moją odpowiedź na temat tego –

Powiązane problemy