Menu

Łączenie ramek danych w R (merge, left_join)

Łączenie ramek danych po wspólnym kluczu: merge() dla złączeń wewnętrznych, lewych, prawych i pełnych, różne nazwy kluczy przez by.x/by.y, rodzina złączeń z dplyr i rbind() do doklejania wierszy.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Dwie tabele, jeden klucz

Prawdziwe dane rzadko mieszczą się w jednej tabeli. Klienci są w jednej ramce danych, ich zamówienia w innej, a pytanie "ile wydał każdy klient?" wymaga obu. Łączy je klucz: kolumna obecna w każdej tabeli, która identyfikuje ten sam obiekt. Łączenie tabel po kluczu to join (słowo z SQL) albo merge (słowo z bazowego R); to ta sama operacja.

Oto para tabel używana w dalszej części strony. Zauważ, że klient 5 złożył zamówienie, ale nie ma go w tabeli klientów, a klienci 2 i 4 nigdy nic nie zamówili:

Niedopasowania są celowe: to, co złączenie robi z niedopasowanymi wierszami, właśnie odróżnia typy złączeń.

merge(): domyślnie złączenie wewnętrzne

merge(x, y, by = "key") dopasowuje wiersze o równych kluczach i skleja ich kolumny. Domyślnie zachowuje tylko klucze obecne w obu tabelach, czyli wykonuje złączenie wewnętrzne (inner join):

Wracają trzy wiersze. Ana pojawia się dwa razy: ma dwa zamówienia, a złączenie tworzy jeden wiersz wyniku na każdą dopasowaną parę. Bena i Dany nie ma (brak zamówień), podobnie jak tajemniczego zamówienia klienta 5 (brak klienta). Złączenie wewnętrzne po cichu odrzuca niedopasowane wiersze z obu tabel. To dokładnie to, czego chcesz, gdy interesują cię tylko pełne pary, i cichy błąd utraty danych, gdy nie.

Złączenia lewe, prawe i pełne: all.x, all.y, all

Żeby zachować niedopasowane wiersze, powiedz, wiersze której tabeli są nietykalne. all.x = TRUE zachowuje każdy wiersz pierwszej tabeli. To złączenie lewe (left join), najczęściej używane w praktyce:

Teraz Ben i Dana zostają, z NA w amount, co znaczy "ten klient istnieje, ale nie dopasowano żadnego zamówienia". Te NA niosą informację, a nie są śmieciami: is.na(result$amount) to dokładnie lista klientów, którzy nigdy nic nie zamówili (pracę z nimi opisuje artykuł o brakujących wartościach). Pozostałe warianty to ten sam pomysł skierowany gdzie indziej: all.y = TRUE zachowuje każdy wiersz drugiej tabeli (złączenie prawe: zamówienie nieznanego klienta 5 zostałoby z NA w name), a all = TRUE zachowuje wszystko z obu stron (złączenie pełne).

Wybieraj, zadając pytanie: których wierszy nie wolno mi stracić? Wzbogacanie tabeli głównej danymi ze słownika: złączenie lewe, tabela główna pierwsza. Audyt w obu kierunkach: złączenie pełne.

Różne nazwy kluczy: by.x i by.y

Tabele rzadko zgadzają się co do nazw: id w jednej, customer_id w drugiej. Nie zmieniaj nazw, tylko podaj merge() obie:

Wynik zachowuje nazwę klucza z pierwszej tabeli. Podobna sprawa: jeśli dwie tabele mają wspólne nazwy kolumn, które nie są kluczem (np. obie mają date), merge dodaje do nich przyrostki date.x i date.y. Zmień ich nazwy od razu, bo czyta się je fatalnie.

Złączenia w dplyr

dplyr daje każdemu typowi złączenia osobny czasownik, więc intencja jest w nazwie funkcji, a nie w argumentach-flagach (przykład statyczny, bo piaskownica uruchamia tylko bazowy R):

library(dplyr)

left_join(customers, orders, by = "id")
inner_join(customers, orders, by = "id")
full_join(customers, orders, by = "id")
left_join(customers, orders, by = c("id" = "customer_id"))  # different names

Poza czytelnością left_join() zachowuje kolejność wierszy pierwszej tabeli (merge() sortuje po kluczu) i głośno ostrzega przed dopasowaniami wiele do wielu. Całą rodzinę czasowników opisuje wprowadzenie do dplyr.

Niedocenianym członkiem rodziny jest anti_join(): zwraca wiersze pierwszej tabeli, które nie mają dopasowania w drugiej, bez dodawania kolumn, same resztki:

anti_join(customers, orders, by = "id")   # customers who never ordered

To pytanie ("które wiersze się nie dopasowały?") ciągle pojawia się przy czyszczeniu danych (niedopasowane ID, osierocone rekordy, nieudane wyszukiwania), a anti_join() odpowiada na nie jednym wywołaniem tam, gdzie bazowy R potrzebuje customers[!(customers$id %in% orders$id), ].

Doklejanie wierszy: rbind()

Złączenie łączy kolumny dwóch tabel. Gdy zamiast tego masz dwie partie wierszy tego samego rodzaju, np. zamówienia ze stycznia i z lutego, doklejasz je przez rbind():

Wymaganie jest ścisłe: obie ramki danych muszą mieć te same nazwy kolumn (w dowolnej kolejności, bo rbind dopasowuje po nazwie). Brakująca albo dodatkowa kolumna to błąd, a nie wypełnienie przez NA. Gdy kolumny w partiach się rozjechały, bind_rows() z dplyr jest bardziej wyrozumiałe: wyrównuje po nazwie i wypełnia luki przez NA.

Eksplozja zduplikowanych kluczy

Klasyczny wypadek przy złączeniach: klucze, które uważano za unikalne, wcale takie nie są, i to w obu tabelach. Każde dopasowanie łączy się z każdym dopasowaniem i wiersze się mnożą:

Dwa wiersze złączone z dwoma wierszami dają cztery: każde x w parze z każdym y. Na prawdziwych danych tak właśnie tabela z 10 000 wierszy zamienia się w 3 miliony wierszy i podwojoną sumę przychodów. merge() robi to po cichu. Obroną jest nawyk: przed złączeniem sprawdź klucz, który uważasz za unikalny (anyDuplicated(customers$id) powinno zwrócić 0), a po złączeniu porównaj nrow() z tym, czego się spodziewasz.

Co warto zapamiętać

  • merge(x, y, by = "key") to złączenie wewnętrzne: niedopasowane wiersze znikają po cichu.
  • all.x = TRUE (lewe), all.y = TRUE (prawe), all = TRUE (pełne) zachowują niedopasowane wiersze i wypełniają je przez NA.
  • Różne nazwy kluczy: by.x / by.y w bazowym R, by = c("a" = "b") w dplyr.
  • dplyr nazywa każde złączenie osobno; anti_join(), czyli wiersze, które się nie dopasowały, to ten niedoceniany.
  • rbind() dokleja tabele o tym samym kształcie; kolumny muszą pasować po nazwie.
  • Zduplikowane klucze po cichu mnożą wiersze: sprawdzaj anyDuplicated() przed złączeniem i nrow() po nim.

Dalej: przekształcanie między formatem szerokim i długim przez pivot_longer() i pivot_wider().

Najczęściej zadawane pytania

Jak połączyć dwie ramki danych w R?

Użyj merge(x, y, by = "key") ze wspólną kolumną klucza. Domyślnie wykonuje złączenie wewnętrzne: zostają tylko wiersze, których klucz występuje w obu ramkach. Dodaj all.x = TRUE dla złączenia lewego, all.y = TRUE dla prawego albo all = TRUE dla pełnego.

Jak zrobić left join w R?

W bazowym R: merge(x, y, by = "key", all.x = TRUE) zachowuje każdy wiersz x i wypełnia kolumny y wartością NA tam, gdzie nie ma dopasowania. W dplyr: left_join(x, y, by = "key") daje ten sam wynik i dodatkowo zachowuje oryginalną kolejność wierszy x, czego merge() nie robi.

Jak połączyć ramki danych, gdy kolumny klucza mają różne nazwy?

Podaj merge() obie nazwy: merge(x, y, by.x = "id", by.y = "customer_id"). W dplyr odpowiednikiem jest left_join(x, y, by = c("id" = "customer_id")) albo, z nowoczesną funkcją pomocniczą, by = join_by(id == customer_id).

Czym różni się merge od rbind w R?

Łączą w różnych wymiarach. merge() dopasowuje wiersze dwóch tabel po kluczu i łączy ich kolumny, czyli wykonuje złączenie. rbind() dokleja wiersze jednej tabeli pod wierszami drugiej i obie muszą mieć te same nazwy kolumn. Miesięczne pliki z identycznymi kolumnami wymagają rbind(), a klienci plus zamówienia wymagają merge().

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ