Συγχώνευση πλαισίων δεδομένων στο R: Πλήρης και μερική αντιστοίχιση

⚡ Έξυπνη Σύνοψη

Η συγχώνευση πλαισίων δεδομένων στο R ενώνει δύο πίνακες σε μία ή περισσότερες στήλες κοινόχρηστου κλειδιού. Η συνάρτηση merge() καλύπτει εσωτερικές, αριστερές, δεξιές και πλήρεις ενώσεις, και αυτή η αναλυτική παρουσίαση δείχνει τόσο μια πλήρη όσο και μια μερική αντιστοίχιση.

  • 🔑 Βασικές στήλες: Η merge() ενώνει τις εντολές by, ή by.x και by.y όταν το κλειδί φέρει διαφορετικό όνομα σε κάθε πλαίσιο.
  • 🔗 Πλήρης αγώνας: Η προεπιλεγμένη εσωτερική ένωση διατηρεί μόνο τις γραμμές των οποίων το κλειδί εμφανίζεται και στα δύο πλαίσια δεδομένων.
  • 🧩 Μερικός αγώνας: Η ρύθμιση all.x = TRUE διατηρεί κάθε γραμμή του πρώτου πλαισίου και γεμίζει τα κενά με NA.
  • 📐 Έλεγχος διαστάσεων: Συγκρίνετε τη συνάρτηση dim() πριν και μετά από μια συγχώνευση για να εντοπίσετε γραμμές που χάθηκαν ή διπλασιάστηκαν από την ένωση.
  • ⚙️ Έλεγχος Συμμετοχής: Οι σημαίες all, all.x και all.y επιλέγουν εσωτερική, αριστερή, δεξιά ή πλήρη εξωτερική συμπεριφορά.
  • Σύγχρονη Εναλλακτική: Το dplyr ονομάζει το καθένα ενώνεται με το ίδιο το ρήμα και διατηρεί την αρχική σειρά γραμμών.

Συγχώνευση πλαισίων δεδομένων στο R

Πολύ συχνά, έχουμε δεδομένα από πολλές πηγές. Για να κάνουμε μια ανάλυση, πρέπει συγχώνευση δύο πλαίσια δεδομένων μαζί με ένα ή περισσότερα κοινές μεταβλητές κλειδιού.

Τύποι συγχώνευσης (Join) στην R

Πριν εξετάσουμε τα παραδείγματα, είναι χρήσιμο να γνωρίζουμε ότι η συνάρτηση merge() εκτελεί κάθε τύπο σύνδεσης που αναμένει ένας χρήστης SQL. Η συμπεριφορά ελέγχεται από τα ορίσματα all, all.x και all.y και όχι από διαφορετικό όνομα συνάρτησης.

Τύπος συμμετοχής Διατηρούνται σειρές κλήση συγχώνευσης() ισοδύναμο dplyr
Εσωτερική ένωση (προεπιλογή) Μόνο κλειδιά υπάρχουν και στα δύο πλαίσια συγχώνευση(x, y, από = “k”) inner_join(x, y, από = “k”)
Αριστερή εξωτερική ένωση Όλες οι γραμμές του x, NA όπου το y δεν έχει καμία αντιστοιχία συγχώνευση(x, y, από = “k”, all.x = TRUE) left_join(x, y, από = “k”)
Δεξιά εξωτερική ένωση Όλες οι γραμμές του y, NA όπου το x δεν έχει καμία αντιστοιχία συγχώνευση(x, y, από = “k”, all.y = TRUE) right_join(x, y, από = “k”)
Πλήρης εξωτερική ένωση Κάθε γραμμή και από τα δύο πλαίσια συγχώνευση(x, y, από = “k”, όλα = TRUE) full_join(x, y, από = “k”)
Διασταυρούμενη συμμετοχή Κάθε συνδυασμός γραμμών συγχώνευση(x, y, από = NULL) cross_join(x, y)

Δύο λεπτομέρειες που αξίζει να θυμάστε πριν από την πρώτη κλήση:

  • Αν παραλείψουμε το , η R συγχωνεύεται σε κάθε όνομα στήλης που μοιράζονται τα δύο πλαίσια, κάτι που σπάνια είναι αυτό που θέλουμε.
  • Η merge() ταξινομεί το αποτέλεσμα κατά στήλη-κλειδί· η συνάρτηση pass sort = FALSE διατηρεί την εισερχόμενη σειρά.

Πλήρης αντιστοιχία

Μια πλήρης αντιστοίχιση επιστρέφει μόνο τις τιμές που έχουν αντίστοιχο στον πίνακα προορισμού. Οι γραμμές χωρίς αντιστοίχιση αφαιρούνται από το νέο πλαίσιο δεδομένων. Μια μερική αντιστοίχιση, αντίθετα, διατηρεί αυτές τις γραμμές και γεμίζει τις στήλες που λείπουν με NA.

Θα δούμε ένα απλό εσωτερική σύνδεση. Η λέξη-κλειδί εσωτερικής ένωσης επιλέγει εγγραφές που έχουν αντίστοιχες τιμές και στους δύο πίνακες. Για να ενώσουμε δύο σύνολα δεδομένων, μπορούμε να χρησιμοποιήσουμε τη συνάρτηση merge(). Θα χρησιμοποιήσουμε τρία επιχειρήματα:

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

Παράδειγμα:

Δημιουργήστε το πρώτο σύνολο δεδομένων με μεταβλητές

  • επώνυμο
  • εθνικότητα

Δημιουργήστε δεύτερο σύνολο δεδομένων με μεταβλητές

  • επώνυμο
  • κινηματογράφος

Η κοινή μεταβλητή-κλειδί είναι το επώνυμο. Μπορούμε να συγχωνεύσουμε και τα δύο πλαίσια δεδομένων και ελέγξτε ότι η διαστασιολόγηση είναι 7×3.

Προσθέτουμε stringsAsFactors=FALSE στο πλαίσιο δεδομένων επειδή δεν θέλουμε R για να μετατρέψετε τις συμβολοσειρές σε παράγοντας; η μεταβλητή θα πρέπει να παραμείνει ένα διάνυσμα χαρακτήρων. Από την έκδοση R 4.0.0, αυτό είναι ήδη το προεπιλεγμένο για το data.frame(), επομένως το όρισμα είναι προαιρετικό στον νέο κώδικα και ακίνδυνο στον παλιό κώδικα.

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

Παραγωγή:

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

Ας συγχωνεύσουμε πλαίσια δεδομένων όταν οι κοινές μεταβλητές κλειδιού έχουν διαφορετικά ονόματα.

Αλλάζουμε επώνυμο σε όνομα στο πλαίσιο δεδομένων ταινιών. Χρησιμοποιούμε τη συνάρτηση identical(x1, x2) για να ελέγξουμε αν και τα δύο πλαίσια δεδομένων είναι πανομοιότυπα.

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

Παραγωγή:

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

Παραγωγή:

## [1] TRUE

Αυτό δείχνει ότι η λειτουργία συγχώνευσης εκτελείται ακόμη και αν τα ονόματα των στηλών είναι διαφορετικά.

Μερικός αγώνας

Η εσωτερική ένωση παραπάνω απέρριψε αθόρυβα οτιδήποτε χωρίς αντίστοιχο. Δεν αποτελεί έκπληξη το γεγονός ότι δύο πλαίσια δεδομένων δεν έχουν τις ίδιες κοινές μεταβλητές κλειδιού. πλήρης αντιστοίχιση, επιστρέφει το πλαίσιο δεδομένων αποκλειστικά σειρές που βρίσκονται τόσο στο πλαίσιο δεδομένων x όσο και στο y. Με μερική συγχώνευση, είναι δυνατό να διατηρηθούν οι σειρές χωρίς αντίστοιχες σειρές στο άλλο πλαίσιο δεδομένων. Αυτές οι σειρές θα έχουν NA σε εκείνες τις στήλες που συνήθως γεμίζουν με τιμές από το y. Μπορούμε να το κάνουμε αυτό ορίζοντας all.x= TRUE.

Για παράδειγμα, μπορούμε να προσθέσουμε έναν νέο παραγωγό, τον Lucas, στο πλαίσιο δεδομένων παραγωγού χωρίς τις αναφορές ταινιών στο πλαίσιο δεδομένων ταινιών. Αν ορίσουμε all.x= FALSE, η R θα ενώσει μόνο τις αντίστοιχες τιμές και στα δύο σύνολα δεδομένων. Στην περίπτωσή μας, ο παραγωγός Lucas δεν θα ενωθεί στο αποτέλεσμα, επειδή λείπει από ένα σύνολο δεδομένων.

Ας δούμε τη διάσταση κάθε εξόδου όταν καθορίζουμε όλα.x= TRUE και πότε όχι.

# 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

Παραγωγή:

Η έξοδος της κονσόλας παρακάτω δείχνει την επιπλέον σειρά Lucas, με τον NA να αντικαθιστά τον τίτλο της ταινίας που λείπει.

Έξοδος κονσόλας της μερικής συγχώνευσης που εμφανίζει τον Lucas με NA στη στήλη τίτλου

# Compare the dimension of each data frame
dim(m1)

Παραγωγή:

## [1] 7 3
dim(m2)

Παραγωγή:

## [1] 7 3
dim(m3)

Παραγωγή:

## [1] 8 3

Όπως μπορούμε να δούμε, το νέο πλαίσιο δεδομένων είναι 8×3, σε σύγκριση με 7×3 για τα m1 και m2. Το R γεμίζει τη στήλη τίτλου με NA για τον Lucas, τον παραγωγό που δεν έχει αντίστοιχη γραμμή στο πλαίσιο δεδομένων ταινιών.

merge() vs dplyr Ενώσεις στην R

Η βάση R λύνει κάθε σύνδεση με μία συνάρτηση και ένα σύνολο σημαιών. dplyr Το πακέτο δίνει σε κάθε join το δικό του ρήμα, το οποίο πολλές ομάδες βρίσκουν πιο εύκολο να διαβάσουν σε μια διοχέτευση.

Κριτήρια Βασική συγχώνευση() dplyr ενώνει
Επιλογή της συμμετοχής all.x / all.y / όλες οι σημαίες Ονομάζεται στο ρήμα: left_join(), full_join()
Σειρά σειρών Ταξινόμηση κατά κλειδί εκτός εάν η ταξινόμηση = FALSE Η σειρά του αριστερού πίνακα διατηρείται
Ταχύτητα σε μεγάλα καρέ Βραδύτερη Γενικά πιο γρήγορα
Λείπει η βασική στήλη Αποτυγχάνει αργά ή συγχωνεύεται σε λάθος στήλες Σφάλματα αμέσως
Εξαρτήσεις Βάση R, δεν υπάρχει τίποτα για εγκατάσταση Απαιτείται το πακέτο dplyr

Οι δύο συγχωνεύσεις που φαίνονται παραπάνω μεταφράζονται απευθείας σε ρήματα dplyr:

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

Η βασική merge() είναι η ασφαλέστερη επιλογή μέσα σε ένα πακέτο που δεν θα πρέπει να περιέχει εξαρτήσεις. Η dplyr είναι η καλύτερη επιλογή σε μια διαδραστική ανάλυση, όπου η αναγνωσιμότητα και η ταχύτητα έχουν μεγαλύτερη σημασία.

Συνηθισμένα σφάλματα συγχώνευσης στην R και πώς να τα διορθώσετε

Τα περισσότερα προβλήματα συγχώνευσης ανακοινώνονται ως απροσδόκητος αριθμός γραμμών και όχι ως μήνυμα σφάλματος, επομένως ο έλεγχος της dim() μετά από κάθε σύνδεση είναι μια συνήθεια που αξίζει να καλλιεργηθεί.

  • Το αποτέλεσμα έχει περισσότερες γραμμές από οποιαδήποτε από τις δύο εισόδους. Ένα κλειδί που επαναλαμβάνεται και στα δύο πλαίσια παράγει μια ένωση πολλά-προς-πολλά και η R επιστρέφει κάθε συνδυασμό. Ελέγξτε τα κλειδιά με το table(duplicated(x$k)) πριν από τη συγχώνευση.
  • Το αποτέλεσμα είναι κενό. Οι στήλες κλειδιών συνήθως διαφέρουν ως προς τον τύπο τους ή η μία περιέχει κενά στο τέλος. Εκτελέστε την εντολή str() και στα δύο πλαίσια και καθαρίστε το κλειδί με την εντολή trimws() πριν από τη συγχώνευση.
  • Οι στήλες επιστρέφουν ως title.x και title.y. Και τα δύο πλαίσια φέρουν μια μη βασική στήλη με το ίδιο όνομα. Περάστε τα επιθήματα = c(“_producer”, “_film”) για να κάνετε την προέλευση προφανή.
  • Οι σειρές δεν βρίσκονται πλέον στην αρχική τους σειρά. Η merge() ταξινομεί το κλειδί από προεπιλογή. Προσθέστε sort = FALSE ή χρησιμοποιήστε μια σαφής ταξινόμηση έπειτα.
  • Μια βασική σύγκριση αποτυγχάνει σε παράγοντες. Σύγκριση χαρακτήρων, όχι επιπέδων παραγόντων: τυλίξτε το κλειδί στο as.character() πριν συγχωνεύσετε πλαίσια που δημιουργήθηκαν με παλαιότερες προεπιλογές R.

Όταν η ίδια συγχώνευση πρέπει να εκτελείται επανειλημμένα, τυλίξτε την σε ένα λειτουργία που ορίζεται από το χρήστη επομένως τα ορίσματα δεν μπορούν να μεταβάλλονται μεταξύ των εκτελέσεων.

Συχνές Ερωτήσεις

Η R συγχωνεύει κάθε όνομα στήλης που μοιράζονται τα δύο πλαίσια. Με μία κοινόχρηστη στήλη αυτό είναι βολικό. με αρκετές περιορίζει σιωπηλά το αποτέλεσμα και με καμία επιστρέφει μια διασταυρούμενη ένωση. Η ρητή ονομασία του κλειδιού αποφεύγει και τις τρεις εκπλήξεις.

Όχι σε μία μόνο κλήση merge(). Συνδέστε τις κλήσεις σε αλυσίδα ή διπλώστε μια λίστα με Reduce(function(x, y) merge(x, y, by = “k”), list(df1, df2, df3)). Επαληθεύστε τον αριθμό των γραμμών μετά από κάθε βήμα, επειδή τα διπλότυπα κλειδιά συντίθενται γρήγορα.

Και τα δύο πλαίσια περιείχαν μια μη βασική στήλη με το ίδιο όνομα, επομένως η R τα αποσαφηνίζει. Περνάμε τα επιθήματα = c(“_producer”, “_film”) για να δώσουμε στα αντίγραφα ονόματα με νόημα ή παραλείπουμε την περιττή στήλη πριν από τη συγχώνευση.

Η συνάρτηση No. merge() ταξινομεί το αποτέλεσμα στη στήλη κλειδιού από προεπιλογή. Περάστε την sort = FALSE για να διατηρήσετε την εισερχόμενη παραγγελία ή χρησιμοποιήστε ένα dplyr ένωση, η οποία διατηρεί τη σειρά του αριστερού πλαισίου.

Δώστε ένα διάνυσμα: merge(x, y, by = c(“επώνυμο”, “έτος”)). Όταν τα ονόματα διαφέρουν, μεταβιβάστε τα αντίστοιχα διανύσματα στις μεταβλητές by.x και by.y. Και τα δύο διανύσματα πρέπει να εμφανίζουν τις στήλες με την ίδια σειρά.

Χρησιμοποιήστε την εντολή by = “row.names” ή τη συντομογραφία by = 0. Η R προσθέτει ξανά τα ονόματα γραμμών ως στήλη που ονομάζεται Row.names, την οποία συνήθως θέλετε να μετονομάσετε ή να αφαιρέσετε πριν συνεχίσετε την ανάλυση.

Περιγράψτε τα δύο πλαίσια και τον αριθμό των γραμμών και ένας βοηθός τεχνητής νοημοσύνης θα υποδείξει διπλότυπα κλειδιά ως πιθανή αιτία και θα προτείνει έλεγχο duplicated(). Επιβεβαιώστε τη διάγνωση με τα δικά σας δεδομένα πριν αλλάξετε τη σύνδεση.

Ναί. Rstudio Η έκδοση Desktop 2023.09.0 και οι νεότερες εκδόσεις διαθέτουν δυνατότητα εγγραφής GitHub Copilot Ενσωμάτωση που συντάσσει μια συγχώνευση από ένα σχόλιο. Ελέγξτε τον τύπο σύνδεσης που επιλέγει, καθώς μια λανθασμένη σημαία αλλάζει τον αριθμό των γραμμών σιωπηλά.

Συνοψίστε αυτήν την ανάρτηση με: