dplyr σε R Tutorial: Συγχώνευση & Ένωση Δεδομένων με Παραδείγματα
⚡ Έξυπνη Σύνοψη
Το dplyr συγχωνεύει και ενώνει πλαίσια δεδομένων σε R με τέσσερα ρήματα: left_join(), right_join(), inner_join() και full_join(). Το συνοδευτικό πακέτο tidyr αναδιαμορφώνει στη συνέχεια το ενωμένο αποτέλεσμα χρησιμοποιώντας gather(), spread(), separate() και unite().
Εισαγωγή στην Ανάλυση Δεδομένων
Πριν από οποιαδήποτε συμμετοχή ή ανανέωσηping Το ρήμα έχει νόημα, βοηθάει να δούμε πού ταιριάζει ο χειρισμός δεδομένων. Ανάλυση δεδομένων μπορεί να χωριστεί σε τρία μέρη:
- Extracσμού: Αρχικά, πρέπει να συλλέξουμε τα δεδομένα από πολλές πηγές και να τα συνδυάσουμε.
- Μεταμορφώστε: Αυτό το βήμα περιλαμβάνει τον χειρισμό δεδομένων. Αφού έχουμε ενοποιήσει όλες τις πηγές δεδομένων, μπορούμε να αρχίσουμε να καθαρίζουμε τα δεδομένα.
- Φαντάζομαι: Η τελευταία κίνηση είναι να οπτικοποιήσουμε τα δεδομένα μας για να ελέγξουμε την παρατυπία.
Το παρακάτω διάγραμμα δείχνει πώς συνδέονται τα τρία στάδια.

Μία από τις σημαντικότερες προκλήσεις που αντιμετωπίζουν οι επιστήμονες δεδομένων είναι ο χειρισμός δεδομένων. Τα δεδομένα δεν είναι ποτέ διαθέσιμα στην επιθυμητή μορφή. Οι επιστήμονες δεδομένων πρέπει να αφιερώνουν τουλάχιστον το μισό χρόνο τους στον καθαρισμό και την επεξεργασία των δεδομένων. Αυτή είναι μια από τις πιο κρίσιμες εργασίες στην εργασία. Εάν η διαδικασία χειρισμού δεδομένων δεν είναι πλήρης, ακριβής και αυστηρή, το μοντέλο δεν θα λειτουργήσει σωστά.
R dplyr
Η R διαθέτει ένα πακέτο που ονομάζεται dplyr και χειρίζεται τον μετασχηματισμό δεδομένων. Είναι δομημένο γύρω από ένα μικρό σύνολο βασικών ρημάτων — filter(), select(), arrange(), mutate() και summarize() — καθώς και μια οικογένεια συναρτήσεων join. Μόλις τα δεδομένα λάβουν τη σωστή μορφή, το ggplot2 μπορεί να τα οπτικοποιήσει.
Θα μάθουμε πώς να χρησιμοποιούμε το πακέτο dplyr για να χειριζόμαστε ένα Πλαίσιο δεδομένωνΕάν το R δεν είναι ακόμα εγκατεστημένο, ακολουθήστε τις οδηγίες Βήματα εγκατάστασης R και RStudioκαι, στη συνέχεια, εκτελέστε την εντολή install.packages(“dplyr”).
Συγχώνευση δεδομένων με το dplyr
Το dplyr παρέχει έναν ωραίο και βολικό τρόπο συνδυασμού συνόλων δεδομένων. Μπορεί να έχουμε πολλές πηγές δεδομένων εισόδου και κάποια στιγμή πρέπει να τις συνδυάσουμε. Μια ένωση με dplyr προσθέτει μεταβλητές στα δεξιά του αρχικού συνόλου δεδομένων.
dplyr Συμμετοχές
Ακολουθούν τέσσερις σημαντικοί τύποι συνδέσεων που χρησιμοποιούνται στο dplyr για τη συγχώνευση δύο συνόλων δεδομένων. Και οι τέσσερις λαμβάνουν τα ίδια ορίσματα — τους δύο πίνακες και το κλειδί — και διαφέρουν μόνο ως προς το ποιες γραμμές που δεν ταιριάζουν επιβιώνουν:
| Λειτουργία | Σκοπός | Επιχειρήματα | Πολλαπλά πλήκτρα |
|---|---|---|---|
| left_join() | Συγχώνευση δύο συνόλων δεδομένων. Κρατήστε όλες τις παρατηρήσεις από τον πίνακα προέλευσης | x, y, κατά = “ID” | x, y, από = c("ID", "ID2") |
| right_join() | Συγχώνευση δύο συνόλων δεδομένων. Διατηρήστε όλες τις παρατηρήσεις από τον πίνακα προορισμού | x, y, κατά = “ID” | x, y, από = c("ID", "ID2") |
| εσωτερική σύνδεση() | Συγχώνευση δύο συνόλων δεδομένων. Εξαίρεση όλων των μη ταιριασμένων γραμμών | x, y, κατά = “ID” | x, y, από = c("ID", "ID2") |
| full_join() | Συγχώνευση δύο συνόλων δεδομένων. Διατήρηση όλων των παρατηρήσεων | x, y, κατά = “ID” | x, y, από = c("ID", "ID2") |
Αυτά τα τέσσερα ρήματα αντιστοιχίζονται στις συνδέσεις LEFT, RIGHT, INNER και FULL OUTER του SQLΗ βάση R καταλήγει στα ίδια αποτελέσματα μέσω των ορισμάτων all, all.x και all.y του συγχώνευση().
Θα μελετήσουμε όλους τους τύπους συνδέσεων μέσω ενός απλού παραδείγματος.
Αρχικά, δημιουργούμε δύο σύνολα δεδομένων. Ο Πίνακας 1 περιέχει δύο μεταβλητές, ID και y, ενώ ο Πίνακας 2 συγκεντρώνει ID και z. Σε κάθε περίπτωση, πρέπει να έχουμε ένα κλειδί-ζεύγος μεταβλητός. Στην περίπτωσή μας, η ταυτότητα είναι δική μας κλειδί μεταβλητή. Η συνάρτηση θα αναζητήσει πανομοιότυπες τιμές και στους δύο πίνακες και θα συνδέσει τις τιμές που επιστρέφουν στα δεξιά του πίνακα 1. Το παρακάτω σχήμα δείχνει τους δύο πίνακες δίπλα-δίπλα.
library(dplyr) df_primary <- tribble( ~ID, ~y, "A", 5, "B", 5, "C", 8, "D", 0, "F", 9) df_secondary <- tribble( ~ID, ~z, "A", 30, "B", 21, "C", 22, "D", 25, "E", 29)
dplyr left_join()
Ο πιο συνηθισμένος τρόπος για να συγχωνεύσετε δύο σύνολα δεδομένων είναι να χρησιμοποιήσετε τη συνάρτηση left_join(). Η παρακάτω εικόνα δείχνει ότι το ζεύγος κλειδιών ταιριάζει με τις γραμμές A, B, C και D, ενώ τα E και F απομένουν. Με τη συνάρτηση left_join(), διατηρούμε όλες τις γραμμές στον αρχικό πίνακα και αγνοούμε τις γραμμές που δεν έχουν ζεύγος κλειδιών στον πίνακα προορισμού. Στο παράδειγμά μας, η τιμή E δεν υπάρχει στον πίνακα 1, επομένως η γραμμή αυτή παραλείπεται. Η τιμή F προέρχεται από τον αρχικό πίνακα, επομένως διατηρείται μετά τη συνάρτηση left_join() και επιστρέφει NA στη στήλη z.
Παράδειγμα dplyr left_join()
Το παρακάτω διάγραμμα αναπαράγει τι συμβαίνει κατά τη διάρκεια μιας left_join().
left_join(df_primary, df_secondary, by ='ID')
Παραγωγή:
## # A tibble: 5 x 3 ## ID y.x y.y ## <chr> <dbl> <dbl> ## 1 A 5 30 ## 2 B 5 21 ## 3 C 8 22 ## 4 D 0 25 ## 5 F 9 NA
Σημειώστε ότι όταν και οι δύο πίνακες φέρουν μια στήλη με το ίδιο όνομα, η συνάρτηση dplyr τους αποσαφηνίζει με τα επιθήματα .x και .y που εμφανίζονται παραπάνω.
dplyr right_join()
Η συνάρτηση right_join() λειτουργεί ακριβώς όπως left_join(). Η μόνη διαφορά είναι ότι η σειρά έπεσε. Η τιμή E, διαθέσιμη στο πλαίσιο δεδομένων προορισμού, υπάρχει στον νέο πίνακα και παίρνει την τιμή NA για τη στήλη y.
Παράδειγμα dplyr right_join()
Το παρακάτω διάγραμμα δείχνει την κατοπτρική εικόνα.
right_join(df_primary, df_secondary, by = 'ID')
Παραγωγή:
## # A tibble: 5 x 3 ## ID y.x y.y ## <chr> <dbl> <dbl> ## 1 A 5 30 ## 2 B 5 21 ## 3 C 8 22 ## 4 D 0 25 ## 5 E NA 29
dplyr inner_join()
Όταν οι μη συμβατές παρατηρήσεις δεν έχουν καμία χρησιμότητα, μπορούμε να επιστρέψουμε αποκλειστικά οι σειρές που υπάρχουν στο και οι δύο σύνολα δεδομένων. Αυτή είναι η σωστή επιλογή όταν χρειαζόμαστε ένα πλήρες σύνολο δεδομένων και δεν θέλουμε να καταλογίσουμε τιμές που λείπουν στον μέσο όρο ή τη διάμεσο.
Η συνάρτηση inner_join() έρχεται να βοηθήσει εδώ. Εξαιρεί τις μη ταιριασμένες γραμμές και στις δύο πλευρές.
Παράδειγμα dplyr inner_join()
Το παρακάτω διάγραμμα επισημαίνει τα τέσσερα αναγνωριστικά που επιβιώνουν από την ένωση.
inner_join(df_primary, df_secondary, by ='ID')
Παραγωγή:
## # A tibble: 4 x 3 ## ID y.x y.y ## <chr> <dbl> <dbl> ## 1 A 5 30 ## 2 B 5 21 ## 3 C 8 22 ## 4 D 0 25
dplyr full_join()
Τέλος, η συνάρτηση full_join() διατηρεί όλες τις παρατηρήσεις και αντικαθιστά τις τιμές που λείπουν με NA.
Παράδειγμα dplyr full_join()
Το παρακάτω διάγραμμα δείχνει κάθε αναγνωριστικό και από τους δύο πίνακες που επιβιώνει από την ένωση.
full_join(df_primary, df_secondary, by = 'ID')
Παραγωγή:
## # A tibble: 6 x 3 ## ID y.x y.y ## <chr> <dbl> <dbl> ## 1 A 5 30 ## 2 B 5 21 ## 3 C 8 22 ## 4 D 0 25 ## 5 F 9 NA ## 6 E NA 29
Πολλαπλά ζεύγη κλειδιών
Τέλος, αλλά εξίσου σημαντικό, μπορούμε να έχουμε πολλά κλειδιά στο σύνολο δεδομένων μας. Σκεφτείτε το ακόλουθο σύνολο δεδομένων όπου έχουμε έτη και μια λίστα προϊόντων που αγόρασε ο πελάτης. Το παρακάτω στιγμιότυπο οθόνης δείχνει τους δύο πίνακες και τις στήλες ID και year που μαζί προσδιορίζουν μια σειρά.
Αν ενώσουμε και τους δύο πίνακες μόνο με βάση το ID, κάθε έτος αντιστοιχίζεται με κάθε έτος και ο αριθμός των γραμμών αυξάνεται κατακόρυφα. Για να διορθώσουμε την κατάσταση, μπορούμε να περάσουμε δύο μεταβλητές ζεύγους κλειδιών. Δηλαδή, το ID και το year, τα οποία εμφανίζονται και στα δύο σύνολα δεδομένων. Μπορούμε να χρησιμοποιήσουμε τον ακόλουθο κώδικα για να συγχωνεύσουμε τον πίνακα 1 και τον πίνακα 2:
df_primary <- tribble( ~ID, ~year, ~items, "A", 2015,3, "A", 2016,7, "A", 2017,6, "B", 2015,4, "B", 2016,8, "B", 2017,7, "C", 2015,4, "C", 2016,6, "C", 2017,6) df_secondary <- tribble( ~ID, ~year, ~prices, "A", 2015,9, "A", 2016,8, "A", 2017,12, "B", 2015,13, "B", 2016,14, "B", 2017,6, "C", 2015,15, "C", 2016,15, "C", 2017,13) left_join(df_primary, df_secondary, by = c('ID', 'year'))
Παραγωγή:
## # A tibble: 9 x 4 ## ID year items prices ## <chr> <dbl> <dbl> <dbl> ## 1 A 2015 3 9 ## 2 A 2016 7 8 ## 3 A 2017 6 12 ## 4 B 2015 4 13 ## 5 B 2016 8 14 ## 6 B 2017 7 6 ## 7 C 2015 4 15 ## 8 C 2016 6 15 ## 9 C 2017 6 13
Από την έκδοση 1.1.0 (Ιανουάριος 2023) το ίδιο κλειδί μπορεί να γραφτεί ως join_by(ID, year) και το dplyr πλέον προειδοποιεί για απροσδόκητες αντιστοιχίσεις πολλών προς πολλά, καθώς το Ανακοίνωση συμμετοχής στο dplyr 1.1.0 εξηγεί.
Λειτουργίες καθαρισμού δεδομένων στο R
Η συγχώνευση λύνει μόνο το μισό πρόβλημα, επειδή ο συνδυασμένος πίνακας πρέπει ακόμη να αναδιαμορφωθεί. Ακολουθούν οι τέσσερις σημαντικές συναρτήσεις για την τακτοποίηση (καθαρισμό) των δεδομένων:
| Λειτουργία | Σκοπός | Επιχειρήματα |
|---|---|---|
| μαζεύω() | Μετατρέψτε τα δεδομένα από ευρεία σε μακρά | (δεδομένα, κλειδί, τιμή, na.rm = FALSE) |
| εξάπλωση() | Μετατρέψτε τα δεδομένα από μακρύ σε μεγάλο | (δεδομένα, κλειδί, τιμή) |
| ξεχωριστός() | Διαχωρίστε μια μεταβλητή σε δύο | (δεδομένα, στήλη, σε, sep = “”, αφαίρεση = TRUE) |
| ενώνω() | Ενώστε δύο μεταβλητές σε μία | (δεδομένα, στήλη, συγκέντρωση, διαχωρισμός = “”, αφαίρεση = ΑΛΗΘΗΣ) |
Σημείωση έκδοσης: Οι συναρτήσεις gather() και spread() αντικαταστάθηκαν από τις συναρτήσεις pivot_longer() και pivot_wider() στο tidyr 1.0.0, και η συνάρτηση separate() από την οικογένεια separate_wider_delim() στο tidyr 1.3.0. Οι αντικατασταθείσες συναρτήσεις εξακολουθούν να εκτελούνται, επομένως κάθε παράδειγμα παρακάτω λειτουργεί, αλλά ο νέος κώδικας θα πρέπει να προτιμά τις νεότερες οικογένειες που εμφανίζονται στο περιστρεφόμενο βινιέτα tidyrΗ .unite() παραμένει τρέχουσα.
Χρησιμοποιούμε το πακέτο tidyr, μέρος της συλλογής tidyverse, για τον χειρισμό, τον καθαρισμό και την οπτικοποίηση δεδομένων. Εάν η R εγκαταστάθηκε με το Anaconda, το πακέτο είναι ήδη διαθέσιμο από https://anaconda.org/r/r-tidyr.
Εάν δεν είναι ήδη εγκατεστημένο, πληκτρολογήστε την ακόλουθη εντολή για να εγκαταστήσετε το tidyr:
install.packages("tidyr")
μαζεύω()
Ο στόχος της συνάρτησης gather() είναι να μετατρέψει τα δεδομένα από wide σε long.
Σύνταξη
gather(data, key, value, na.rm = FALSE) Arguments: -data: The data frame used to reshape the dataset -key: Name of the new column created -value: Select the columns used to fill the key column -na.rm: Remove missing values. FALSE by default
Παράδειγμα
Παρακάτω, μπορούμε να οπτικοποιήσουμε την έννοια του reshaping από πλάτος σε μήκος. Θέλουμε να δημιουργήσουμε μια μόνο στήλη με το όνομα ανάπτυξη, η οποία θα συμπληρώνεται από τις γραμμές των μεταβλητών τετάρτου. Το παρακάτω σχήμα δείχνει τον ευρύ πίνακα στα αριστερά και τον αναδιαμορφωμένο μακρύ πίνακα στα δεξιά.
library(tidyr) # Create a messy dataset messy <- data.frame( country = c("A", "B", "C"), q1_2017 = c(0.03, 0.05, 0.01), q2_2017 = c(0.05, 0.07, 0.02), q3_2017 = c(0.04, 0.05, 0.01), q4_2017 = c(0.03, 0.02, 0.04)) messy
Παραγωγή:
## country q1_2017 q2_2017 q3_2017 q4_2017 ## 1 A 0.03 0.05 0.04 0.03 ## 2 B 0.05 0.07 0.05 0.02 ## 3 C 0.01 0.02 0.01 0.04
# Reshape the data
tidier <-messy %>%
gather(quarter, growth, q1_2017:q4_2017)
tidier
Παραγωγή:
## country quarter growth ## 1 A q1_2017 0.03 ## 2 B q1_2017 0.05 ## 3 C q1_2017 0.01 ## 4 A q2_2017 0.05 ## 5 B q2_2017 0.07 ## 6 C q2_2017 0.02 ## 7 A q3_2017 0.04 ## 8 B q3_2017 0.05 ## 9 C q3_2017 0.01 ## 10 A q4_2017 0.03 ## 11 B q4_2017 0.02 ## 12 C q4_2017 0.04
Στη συνάρτηση gather(), δημιουργούμε δύο νέες μεταβλητές, το quarter και το growth, επειδή το αρχικό μας σύνολο δεδομένων έχει μία μεταβλητή ομάδας, τη χώρα, και τα ζεύγη κλειδιού-τιμής. Στο tidyr 1.0.0 και σε νεότερες εκδόσεις, η ίδια αναδιαμόρφωση γράφεται ως pivot_longer(messy, cols = q1_2017:q4_2017, names_to = “quarter”, values_to = “growth”).
εξάπλωση()
Η συνάρτηση spread() κάνει το αντίθετο από τη συνάρτηση gather().
Σύνταξη
spread(data, key, value) arguments: data: The data frame used to reshape the dataset key: Column to reshape long to wide value: Rows used to fill the new column
Παράδειγμα
Μπορούμε να αναδιαμορφώσουμε το σύνολο δεδομένων tidier ξανά σε messy με την μέθοδο spread().
# Reshape the data
messy_1 <- tidier %>%
spread(quarter, growth)
messy_1
Παραγωγή:
## country q1_2017 q2_2017 q3_2017 q4_2017 ## 1 A 0.03 0.05 0.04 0.03 ## 2 B 0.05 0.07 0.05 0.02 ## 3 C 0.01 0.02 0.01 0.04
Το σύγχρονο ισοδύναμο είναι pivot_wider(tidier, names_from = quarter, values_from = growth).
ξεχωριστός()
Η συνάρτηση separate() χωρίζει μια στήλη σε δύο σύμφωνα με ένα διαχωριστικό. Αυτή η συνάρτηση είναι χρήσιμη σε περιπτώσεις όπου η μεταβλητή είναι ημερομηνία. Η ανάλυσή μας μπορεί να απαιτεί εστίαση στον μήνα και το έτος και θέλουμε να διαχωρίσουμε τη στήλη σε δύο νέες μεταβλητές.
Σύνταξη
separate(data, col, into, sep= "", remove = TRUE) arguments: -data: The data frame used to reshape the dataset -col: The column to split -into: The name of the new variables -sep: Indicates the symbol used that separates the variable, i.e.: "-", "_", "&" -remove: Remove the old column. By default sets to TRUE.
Παράδειγμα
Μπορούμε να χωρίσουμε το τρίμηνο από το έτος στο πιο τακτοποιημένο σύνολο δεδομένων εφαρμόζοντας τη συνάρτηση ξεχωριστή().
separate_tidier <-tidier %>% separate(quarter, c("Qrt", "year"), sep ="_") head(separate_tidier)
Παραγωγή:
## country Qrt year growth ## 1 A q1 2017 0.03 ## 2 B q1 2017 0.05 ## 3 C q1 2017 0.01 ## 4 A q2 2017 0.05 ## 5 B q2 2017 0.07 ## 6 C q2 2017 0.02
ενώνω()
Η συνάρτηση unite() ενώνει δύο στήλες σε μία.
Σύνταξη
unite(data, col, conc ,sep= "", remove = TRUE) arguments: -data: The data frame used to reshape the dataset -col: Name of the new column -conc: Name of the columns to concatenate -sep: Indicates the symbol used that unites the variable, i.e: "-", "_", "&" -remove: Remove the old columns. By default, sets to TRUE
Παράδειγμα
Στο παραπάνω παράδειγμα, διαχωρίσαμε το τρίμηνο από το έτος. Τι γίνεται αν θέλουμε να τα συγχωνεύσουμε; Χρησιμοποιούμε τον ακόλουθο κώδικα:
unit_tidier <- separate_tidier %>%
unite(Quarter, Qrt, year, sep ="_")
head(unit_tidier)
Παραγωγή:
## country Quarter growth ## 1 A q1_2017 0.03 ## 2 B q1_2017 0.05 ## 3 C q1_2017 0.01 ## 4 A q2_2017 0.05 ## 5 B q2_2017 0.07 ## 6 C q2_2017 0.02
Το αναδιαμορφωμένο πλαίσιο δεδομένων είναι πλέον έτοιμο για τα βήματα μοντελοποίησης που καλύπτονται στο υπόλοιπο μέρος. Σειρά εκπαιδευτικών σεμιναρίων R.








