Spajanje okvira podataka u R: potpuno i djelomično podudaranje
⚡ Pametni sažetak
Spajanje podatkovnih okvira u R-u spaja dvije tablice na jednom ili više stupaca s dijeljenim ključem. Funkcija merge() pokriva unutarnje, lijevo, desno i potpuno spajanje, a ovaj vodič demonstrira i potpuno i djelomično podudaranje.

Vrlo često imamo podatke iz više izvora. Da bismo izvršili analizu, moramo spojiti dva podatkovna okvira zajedno s jednim ili više zajedničke ključne varijable.
Vrste spajanja (Join) u R-u
Prije nego što prođemo kroz primjere, korisno je znati da merge() izvršava svaku vrstu spajanja koju SQL korisnik očekuje. Ponašanje je kontrolirano argumentima all, all.x i all.y, a ne drugim nazivom funkcije.
| Vrsta pridruživanja | Redci sačuvani | merge() poziv | ekvivalent dplyr-a |
|---|---|---|---|
| Unutarnji spoj (zadano) | Samo ključevi prisutni u oba okvira | spajanje(x, y, s = “k”) | unutarnji_spajanje(x, y, by = “k”) |
| Lijevi vanjski spoj | Svi retci x, NA gdje y nema podudaranja | spajanje(x, y, po = “k”, sve.x = ISTINA) | lijevo_spajanje(x, y, by = “k”) |
| Desni vanjski spoj | Svi retci y, NA gdje x nema podudaranja | spajanje(x, y, by = “k”, sve.y = ISTINA) | desno_spajanje(x, y, by = “k”) |
| Potpuni vanjski spoj | Svaki red iz oba okvira | spajanje(x, y, od = “k”, sve = ISTINA) | puni_spajanje(x, y, by = “k”) |
| Unakrsno spajanje | Svaka kombinacija redova | spajanje(x, y, s = NULL) | cross_join(x, y) |
Prije prvog poziva vrijedi zapamtiti dva detalja:
- Izostavljanje "by" uzrokuje spajanje R-a na svakom nazivu stupca koji dva okvira dijele, što rijetko želite.
- merge() sortira rezultat prema ključnom stupcu; proslijedite sort = FALSE kako biste zadržali dolazni redoslijed.
Potpuna utakmica
Potpuno podudaranje vraća samo vrijednosti koje imaju ekvivalent u odredišnoj tablici. Redci bez podudaranja izbacuju se iz novog okvira podataka. Djelomično podudaranje, nasuprot tome, zadržava te retke i popunjava nedostajuće stupce s NA.
Vidjet ćemo jednostavan unutarnji spoj. Ključna riječ unutarnje spajanje odabire zapise koji imaju podudarne vrijednosti u obje tablice. Za spajanje dva skupa podataka možemo koristiti funkciju merge(). Koristit ćemo tri argumenta:
merge(x, y, by.x = x, by.y = y) Arguments: -x: The origin data frame -y: The data frame to merge -by.x: The column used for merging in x data frame. Column x to merge on -by.y: The column used for merging in y data frame. Column y to merge on
Primjer:
Stvorite prvi skup podataka s varijablama
- prezime
- državljanstvo
Stvorite drugi skup podataka s varijablama
- prezime
- filmovi
Zajednička ključna varijabla je prezime. Možemo spojiti oboje podatkovni okviri i provjerite je li dimenzionalnost 7×3.
U podatkovni okvir dodajemo stringsAsFactors=FALSE jer ne želimo R pretvoriti nizove u faktor; varijabla bi trebala ostati vektor znakova. Od verzije R 4.0.0 ovo je već zadana vrijednost za data.frame(), pa je argument opcionalan u novom kodu, a bezopasan u starom kodu.
# Create origin dataframe( producers <- data.frame( surname = c("Spielberg","Scorsese","Hitchcock","Tarantino","Polanski"), nationality = c("US","US","UK","US","Poland"), stringsAsFactors=FALSE) # Create destination dataframe movies <- data.frame( surname = c("Spielberg", "Scorsese", "Hitchcock", "Hitchcock", "Spielberg", "Tarantino", "Polanski"), title = c("Super 8", "Taxi Driver", "Psycho", "North by Northwest", "Catch Me If You Can", "Reservoir Dogs","Chinatown"), stringsAsFactors=FALSE) # Merge two datasets m1 <- merge(producers, movies, by.x = "surname") m1 dim(m1)
Izlaz:
surname nationality title 1 Hitchcock UK Psycho 2 Hitchcock UK North by Northwest 3 Polanski Poland Chinatown 4 Scorsese US Taxi Driver 5 Spielberg US Super 8 6 Spielberg US Catch Me If You Can 7 Tarantino US Reservoir Dogs
Spojimo podatkovne okvire kada varijable zajedničkog ključa imaju različita imena.
Mijenjamo prezime u ime u podatkovnom okviru filmova. Koristimo funkciju identical(x1, x2) da provjerimo jesu li oba podatkovna okvira identična.
# Change name of ` movies ` dataframe colnames(movies)[colnames(movies) == 'surname'] <- 'name' # Merge with different key value m2 <- merge(producers, movies, by.x = "surname", by.y = "name") # Print head of the data head(m2)
Izlaz:
##surname nationality title ## 1 Hitchcock UK Psycho ## 2 Hitchcock UK North by Northwest ## 3 Polanski Poland Chinatown ## 4 Scorsese US Taxi Driver ## 5 Spielberg US Super 8 ## 6 Spielberg US Catch Me If You Can
# Check if data are identical
identical(m1, m2)
Izlaz:
## [1] TRUE
Ovo pokazuje da se operacija spajanja izvodi čak i ako su nazivi stupaca različiti.
Djelomično podudaranje
Unutarnji spoj iznad tiho je odbacio sve bez ekvivalenta. Nije iznenađujuće da dva podatkovna okvira nemaju iste zajedničke ključne varijable. U potpuno podudaranje, dataframe se vraća samo redaka koji se nalaze i u x i u podatkovnom okviru. S djelomično spajanje, moguće je zadržati retke bez odgovarajućih redaka u drugom okviru podataka. Ovi redovi će imati NA u onim stupcima koji su obično ispunjeni vrijednostima iz y. To možemo učiniti postavljanjem all.x= TRUE.
Na primjer, možemo dodati novog producenta, Lucasa, u okvir podataka producenta bez referenci filmova u okviru podataka filmova. Ako postavimo all.x= FALSE, R će spojiti samo odgovarajuće vrijednosti u oba skupa podataka. U našem slučaju, producent Lucas neće biti spojen u rezultat jer nedostaje u jednom skupu podataka.
Pogledajmo dimenziju svakog izlaza kada specificiramo all.x= TRUE i kada ne specificiramo.
# Create a new producer add_producer <- c('Lucas', 'US') # Append it to the ` producer` dataframe producers <- rbind(producers, add_producer) # Use a partial merge m3 <-merge(producers, movies, by.x = "surname", by.y = "name", all.x = TRUE) m3
Izlaz:
Izlaz konzole ispod prikazuje dodatni Lucasov redak, gdje NA zamjenjuje nedostajući naslov filma.
# Compare the dimension of each data frame
dim(m1)
Izlaz:
## [1] 7 3
dim(m2)
Izlaz:
## [1] 7 3
dim(m3)
Izlaz:
## [1] 8 3
Kao što vidimo, novi podatkovni okvir je 8×3, u usporedbi sa 7×3 za m1 i m2. R ispunjava stupac naslova s NA za Lucasa, producenta koji nema odgovarajući redak u podatkovnom okviru filma.
merge() vs. dplyr Spajanja u R-u
Bazni R rješava svaki spoj s jednom funkcijom i skupom zastavica. dplyr Paket umjesto toga daje svakom spajanju vlastiti glagol, što mnogi timovi smatraju lakšim za čitanje u cjevovodu.
| Kriteriji | Spajanje baze() | dplyr spajanja |
|---|---|---|
| Odabir spoja | sve.x / sve.y / sve zastavice | Imenovano u glagolu: left_join(), full_join() |
| Redoslijed redaka | Sortirano po ključu osim ako sort = FALSE | Redoslijed lijeve tablice je sačuvan |
| Brzina na velikim okvirima | sporiji | Općenito brže |
| Nedostaje ključni stupac | Kasno ne uspijeva ili se spaja u pogrešnim stupcima | Greške odmah |
| ovisnosti | Baza R, nema što instalirati | Zahtijeva dplyr paket |
Dva gore prikazana spajanja prevode se direktno u dplyr glagole:
library(dplyr) # Same inner join as merge(producers, movies, by.x = "surname", by.y = "name") m4 <- inner_join(producers, movies, by = c("surname" = "name")) # Same partial merge as all.x = TRUE m5 <- left_join(producers, movies, by = c("surname" = "name"))
Osnovna merge() je sigurniji izbor unutar paketa koji ne bi trebao imati ovisnosti. dplyr je bolji izbor u interaktivnoj analizi, gdje su čitljivost i brzina važniji.
Uobičajene pogreške spajanja u R-u i kako ih ispraviti
Većina problema spajanja se najavljuje kao neočekivani broj redaka, a ne kao poruka o pogrešci, stoga je provjera dim() nakon svakog spajanja navika koju vrijedi steći.
- Rezultat ima više redaka od bilo kojeg ulaza. Ključ koji se ponavlja u oba okvira stvara spajanje više-na-više, a R vraća svaku kombinaciju. Pregledajte ključeve pomoću table(duplicated(x$k)) prije spajanja.
- Rezultat je prazan. Ključni stupci se obično razlikuju po vrsti ili jedan od njih sadrži razmake na kraju. Pokrenite str() na oba okvira i očistite ključ pomoću trimws() prije spajanja.
- Kolumne se vraćaju kao naslov.x i naslov.y. Oba okvira nose stupac koji nije ključan s istim imenom. Dodajte sufikse = c(“_producer”, “_film”) kako bi porijeklo bilo očito.
- Redovi više nisu u izvornom redoslijedu. merge() sortira po ključu prema zadanim postavkama. Dodajte sort = FALSE ili upotrijebite eksplicitno sortiranje nakon toga.
- Ključna usporedba ne uspijeva na temelju faktora. Usporedite znakove, a ne razine faktorizacije: ključ se stavi u as.character() prije spajanja okvira stvorenih pod starijim R zadanim postavkama.
Kada se isto spajanje mora ponavljati, zamotajte ga u korisnički definirana funkcija tako da argumenti ne mogu lutati između prolazaka.

