Επέκταση ένθετων στηλών - λιστών με χρήση της γλώσσας R (πακέτο tidyr και συναρτήσεις της οικογένειας unnest)

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

Αυτές οι μορφές έχουν πολλά πλεονεκτήματα: αποθηκεύουν δεδομένα αρκετά συμπαγή και σας επιτρέπουν να αποφύγετε την περιττή αντιγραφή πληροφοριών.

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

Επέκταση ένθετων στηλών - λιστών με χρήση της γλώσσας R (πακέτο tidyr και συναρτήσεις της οικογένειας unnest)

Αυτό το άρθρο είναι μια λογική συνέχεια της δημοσίευσης "Το πακέτο R tidyr και οι νέες του λειτουργίες pivot_longer και pivot_wider". Θα σας βοηθήσει να φέρετε τις μη δομημένες δομές δεδομένων σε μια οικεία και κατάλληλη για ανάλυση μορφή πίνακα χρησιμοποιώντας το πακέτο tidyr, που περιλαμβάνεται στον πυρήνα της βιβλιοθήκης tidyverseκαι την οικογένεια των λειτουργιών του unnest_*().

περιεχόμενο

Εάν ενδιαφέρεστε για την ανάλυση δεδομένων, μπορεί να σας ενδιαφέρει το δικό μου τηλεγράφημα и YouTube καναλιών. Το μεγαλύτερο μέρος του περιεχομένου του οποίου είναι αφιερωμένο στη γλώσσα R.

  1. Εισαγωγή
  2. Χρήστες του GitHub
  3. Αποθετήρια Github
  4. Οι χαρακτήρες του Game of Thrones
  5. Γεωκωδικοποίηση με το Google
  6. Δισκογραφία Sharla Gelfand
  7. Συμπέρασμα

Εισαγωγή

Ορθογώνια (σημείωση του μεταφραστή, δεν βρήκα επαρκείς επιλογές μετάφρασης για αυτόν τον όρο, οπότε θα τον αφήσουμε ως έχει.) είναι η διαδικασία μεταφοράς μη δομημένων δεδομένων με ένθετους πίνακες σε έναν δισδιάστατο πίνακα που αποτελείται από γνωστές γραμμές και στήλες. ΣΕ tidyr Υπάρχουν πολλές λειτουργίες που θα σας βοηθήσουν να επεκτείνετε τις στήλες ένθετων λιστών και να μειώσετε τα δεδομένα σε μια ορθογώνια, πινακοειδή μορφή:

  • unnest_longer() παίρνει κάθε στοιχείο της λίστας στηλών και δημιουργεί μια νέα σειρά.
  • unnest_wider() παίρνει κάθε στοιχείο της λίστας στηλών και δημιουργεί μια νέα στήλη.
  • unnest_auto() καθορίζει αυτόματα ποια λειτουργία είναι καλύτερη για χρήση
    unnest_longer() ή unnest_wider().
  • hoist() παρόμοιο με unnest_wider() αλλά επιλέγει μόνο τα καθορισμένα στοιχεία και σας επιτρέπει να εργαστείτε με πολλά επίπεδα ένθεσης.

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

Για να δείξουμε αυτές τις τεχνικές, θα χρησιμοποιήσουμε το πακέτο repurrrsive, το οποίο παρέχει πολλαπλές σύνθετες λίστες πολλαπλών επιπέδων που προέρχονται από ένα web API.

library(tidyr)
library(dplyr)
library(repurrrsive)

Χρήστες του GitHub

Ας αρχίσουμε gh_users, μια λίστα που περιέχει πληροφορίες για έξι χρήστες του GitHub. Πρώτα ας μεταμορφώσουμε τη λίστα gh_users в κρότουλα πλαίσιο:

users <-   tibble( user = gh_users ) 

Αυτό φαίνεται λίγο αντιφατικό: γιατί να παρέχετε μια λίστα gh_users, σε μια πιο σύνθετη δομή δεδομένων; Αλλά ένα πλαίσιο δεδομένων έχει ένα μεγάλο πλεονέκτημα: συνδυάζει πολλαπλά διανύσματα έτσι ώστε τα πάντα να παρακολουθούνται σε ένα αντικείμενο.

Κάθε στοιχείο αντικειμένου users είναι μια λίστα με όνομα στην οποία κάθε στοιχείο αντιπροσωπεύει μια στήλη.

names(users$user[[1]])
#>  [1] "login"               "id"                  "avatar_url"         
#>  [4] "gravatar_id"         "url"                 "html_url"           
#>  [7] "followers_url"       "following_url"       "gists_url"          
#> [10] "starred_url"         "subscriptions_url"   "organizations_url"  
#> [13] "repos_url"           "events_url"          "received_events_url"
#> [16] "type"                "site_admin"          "name"               
#> [19] "company"             "blog"                "location"           
#> [22] "email"               "hireable"            "bio"                
#> [25] "public_repos"        "public_gists"        "followers"          
#> [28] "following"           "created_at"          "updated_at"

Υπάρχουν δύο τρόποι για να μετατρέψετε τα στοιχεία της λίστας σε στήλες. unnest_wider() παίρνει κάθε στοιχείο και δημιουργεί μια νέα στήλη:

users %>% unnest_wider(user)
#> # A tibble: 6 x 30
#>   login     id avatar_url gravatar_id url   html_url followers_url
#>   <chr>  <int> <chr>      <chr>       <chr> <chr>    <chr>        
#> 1 gabo… 6.60e5 https://a… ""          http… https:/… https://api.…
#> 2 jenn… 5.99e5 https://a… ""          http… https:/… https://api.…
#> 3 jtle… 1.57e6 https://a… ""          http… https:/… https://api.…
#> 4 juli… 1.25e7 https://a… ""          http… https:/… https://api.…
#> 5 leep… 3.51e6 https://a… ""          http… https:/… https://api.…
#> 6 masa… 8.36e6 https://a… ""          http… https:/… https://api.…
#> # … with 23 more variables: following_url <chr>, gists_url <chr>,
#> #   starred_url <chr>, subscriptions_url <chr>, organizations_url <chr>,
#> #   repos_url <chr>, events_url <chr>, received_events_url <chr>,
#> #   type <chr>, site_admin <lgl>, name <chr>, company <chr>, blog <chr>,
#> #   location <chr>, email <chr>, public_repos <int>, public_gists <int>,
#> #   followers <int>, following <int>, created_at <chr>, updated_at <chr>,
#> #   bio <chr>, hireable <lgl>

Σε αυτήν την περίπτωση, έχουμε έναν πίνακα που αποτελείται από 30 στήλες και δεν θα χρειαστούμε τις περισσότερες από αυτές, οπότε μπορούμε να unnest_wider() χρήση hoist(). hoist() μας επιτρέπει να εξαγάγουμε επιλεγμένα στοιχεία χρησιμοποιώντας την ίδια σύνταξη με purrr::pluck():

users %>% hoist(user, 
  followers = "followers", 
  login = "login", 
  url = "html_url"
)
#> # A tibble: 6 x 4
#>   followers login       url                            user             
#>       <int> <chr>       <chr>                          <list>           
#> 1       303 gaborcsardi https://github.com/gaborcsardi <named list [27]>
#> 2       780 jennybc     https://github.com/jennybc     <named list [27]>
#> 3      3958 jtleek      https://github.com/jtleek      <named list [27]>
#> 4       115 juliasilge  https://github.com/juliasilge  <named list [27]>
#> 5       213 leeper      https://github.com/leeper      <named list [27]>
#> 6        34 masalmon    https://github.com/masalmon    <named list [27]>

hoist() αφαιρεί τα καθορισμένα στοιχεία με όνομα από μια λίστα στηλών χρήστηώστε να μπορείτε να σκεφτείτε hoist() όπως η μετακίνηση στοιχείων από την εσωτερική λίστα ενός πλαισίου ημερομηνίας στο ανώτερο επίπεδο.

Αποθετήρια Github

Στοίχιση λίστας gh_repos ξεκινάμε παρόμοια μετατρέποντάς το σε tibble:

repos <- tibble(repo = gh_repos)
repos
#> # A tibble: 6 x 1
#>   repo       
#>   <list>     
#> 1 <list [30]>
#> 2 <list [30]>
#> 3 <list [30]>
#> 4 <list [26]>
#> 5 <list [30]>
#> 6 <list [30]>

Αυτή τη φορά τα στοιχεία χρήστη αντιπροσωπεύουν μια λίστα αποθετηρίων που ανήκουν σε αυτόν τον χρήστη. Κάθε αποθετήριο είναι μια ξεχωριστή παρατήρηση, έτσι σύμφωνα με την έννοια των καθαρών δεδομένων (περίπου τακτοποιημένα δεδομένα) θα πρέπει να γίνουν νέες γραμμές, γι' αυτό χρησιμοποιούμε unnest_longer() και όχι unnest_wider():

repos <- repos %>% unnest_longer(repo)
repos
#> # A tibble: 176 x 1
#>    repo             
#>    <list>           
#>  1 <named list [68]>
#>  2 <named list [68]>
#>  3 <named list [68]>
#>  4 <named list [68]>
#>  5 <named list [68]>
#>  6 <named list [68]>
#>  7 <named list [68]>
#>  8 <named list [68]>
#>  9 <named list [68]>
#> 10 <named list [68]>
#> # … with 166 more rows

Τώρα μπορούμε να χρησιμοποιήσουμε unnest_wider() ή hoist() :

repos %>% hoist(repo, 
  login = c("owner", "login"), 
  name = "name",
  homepage = "homepage",
  watchers = "watchers_count"
)
#> # A tibble: 176 x 5
#>    login       name        homepage watchers repo             
#>    <chr>       <chr>       <chr>       <int> <list>           
#>  1 gaborcsardi after       <NA>            5 <named list [65]>
#>  2 gaborcsardi argufy      <NA>           19 <named list [65]>
#>  3 gaborcsardi ask         <NA>            5 <named list [65]>
#>  4 gaborcsardi baseimports <NA>            0 <named list [65]>
#>  5 gaborcsardi citest      <NA>            0 <named list [65]>
#>  6 gaborcsardi clisymbols  ""             18 <named list [65]>
#>  7 gaborcsardi cmaker      <NA>            0 <named list [65]>
#>  8 gaborcsardi cmark       <NA>            0 <named list [65]>
#>  9 gaborcsardi conditions  <NA>            0 <named list [65]>
#> 10 gaborcsardi crayon      <NA>           52 <named list [65]>
#> # … with 166 more rows

Δώστε προσοχή στη χρήση c("owner", "login"): Αυτό μας επιτρέπει να λάβουμε την τιμή δεύτερου επιπέδου από μια ένθετη λίστα owner. Μια εναλλακτική προσέγγιση είναι να λάβετε ολόκληρη τη λίστα owner και στη συνέχεια χρησιμοποιώντας τη συνάρτηση unnest_wider() βάλτε κάθε στοιχείο του σε μια στήλη:

repos %>% 
  hoist(repo, owner = "owner") %>% 
  unnest_wider(owner)
#> # A tibble: 176 x 18
#>    login     id avatar_url gravatar_id url   html_url followers_url
#>    <chr>  <int> <chr>      <chr>       <chr> <chr>    <chr>        
#>  1 gabo… 660288 https://a… ""          http… https:/… https://api.…
#>  2 gabo… 660288 https://a… ""          http… https:/… https://api.…
#>  3 gabo… 660288 https://a… ""          http… https:/… https://api.…
#>  4 gabo… 660288 https://a… ""          http… https:/… https://api.…
#>  5 gabo… 660288 https://a… ""          http… https:/… https://api.…
#>  6 gabo… 660288 https://a… ""          http… https:/… https://api.…
#>  7 gabo… 660288 https://a… ""          http… https:/… https://api.…
#>  8 gabo… 660288 https://a… ""          http… https:/… https://api.…
#>  9 gabo… 660288 https://a… ""          http… https:/… https://api.…
#> 10 gabo… 660288 https://a… ""          http… https:/… https://api.…
#> # … with 166 more rows, and 11 more variables: following_url <chr>,
#> #   gists_url <chr>, starred_url <chr>, subscriptions_url <chr>,
#> #   organizations_url <chr>, repos_url <chr>, events_url <chr>,
#> #   received_events_url <chr>, type <chr>, site_admin <lgl>, repo <list>

Αντί να σκέφτεστε να επιλέξετε τη σωστή λειτουργία unnest_longer() ή unnest_wider() μπορείς να χρησιμοποιήσεις unnest_auto(). Αυτή η συνάρτηση χρησιμοποιεί διάφορες ευρετικές μεθόδους για να επιλέξει την καταλληλότερη συνάρτηση για τον μετασχηματισμό των δεδομένων και εμφανίζει ένα μήνυμα σχετικά με την επιλεγμένη μέθοδο.

tibble(repo = gh_repos) %>% 
  unnest_auto(repo) %>% 
  unnest_auto(repo)
#> Using `unnest_longer(repo)`; no element has names
#> Using `unnest_wider(repo)`; elements have 68 names in common
#> # A tibble: 176 x 67
#>        id name  full_name owner private html_url description fork  url  
#>     <int> <chr> <chr>     <lis> <lgl>   <chr>    <chr>       <lgl> <chr>
#>  1 6.12e7 after gaborcsa… <nam… FALSE   https:/… Run Code i… FALSE http…
#>  2 4.05e7 argu… gaborcsa… <nam… FALSE   https:/… Declarativ… FALSE http…
#>  3 3.64e7 ask   gaborcsa… <nam… FALSE   https:/… Friendly C… FALSE http…
#>  4 3.49e7 base… gaborcsa… <nam… FALSE   https:/… Do we get … FALSE http…
#>  5 6.16e7 cite… gaborcsa… <nam… FALSE   https:/… Test R pac… TRUE  http…
#>  6 3.39e7 clis… gaborcsa… <nam… FALSE   https:/… Unicode sy… FALSE http…
#>  7 3.72e7 cmak… gaborcsa… <nam… FALSE   https:/… port of cm… TRUE  http…
#>  8 6.80e7 cmark gaborcsa… <nam… FALSE   https:/… CommonMark… TRUE  http…
#>  9 6.32e7 cond… gaborcsa… <nam… FALSE   https:/… <NA>        TRUE  http…
#> 10 2.43e7 cray… gaborcsa… <nam… FALSE   https:/… R package … FALSE http…
#> # … with 166 more rows, and 58 more variables: forks_url <chr>,
#> #   keys_url <chr>, collaborators_url <chr>, teams_url <chr>,
#> #   hooks_url <chr>, issue_events_url <chr>, events_url <chr>,
#> #   assignees_url <chr>, branches_url <chr>, tags_url <chr>,
#> #   blobs_url <chr>, git_tags_url <chr>, git_refs_url <chr>,
#> #   trees_url <chr>, statuses_url <chr>, languages_url <chr>,
#> #   stargazers_url <chr>, contributors_url <chr>, subscribers_url <chr>,
#> #   subscription_url <chr>, commits_url <chr>, git_commits_url <chr>,
#> #   comments_url <chr>, issue_comment_url <chr>, contents_url <chr>,
#> #   compare_url <chr>, merges_url <chr>, archive_url <chr>,
#> #   downloads_url <chr>, issues_url <chr>, pulls_url <chr>,
#> #   milestones_url <chr>, notifications_url <chr>, labels_url <chr>,
#> #   releases_url <chr>, deployments_url <chr>, created_at <chr>,
#> #   updated_at <chr>, pushed_at <chr>, git_url <chr>, ssh_url <chr>,
#> #   clone_url <chr>, svn_url <chr>, size <int>, stargazers_count <int>,
#> #   watchers_count <int>, language <chr>, has_issues <lgl>,
#> #   has_downloads <lgl>, has_wiki <lgl>, has_pages <lgl>,
#> #   forks_count <int>, open_issues_count <int>, forks <int>,
#> #   open_issues <int>, watchers <int>, default_branch <chr>,
#> #   homepage <chr>

Οι χαρακτήρες του Game of Thrones

got_chars έχει την ίδια δομή με gh_users: Αυτό είναι ένα σύνολο από ονομασμένες λίστες, όπου κάθε στοιχείο της εσωτερικής λίστας περιγράφει κάποιο χαρακτηριστικό ενός χαρακτήρα του Game of Thrones. Φέρνοντας got_chars Για την προβολή πίνακα, ξεκινάμε δημιουργώντας ένα πλαίσιο ημερομηνίας, όπως στα προηγούμενα παραδείγματα, και στη συνέχεια μετατρέπουμε κάθε στοιχείο σε ξεχωριστή στήλη:

chars <- tibble(char = got_chars)
chars
#> # A tibble: 30 x 1
#>    char             
#>    <list>           
#>  1 <named list [18]>
#>  2 <named list [18]>
#>  3 <named list [18]>
#>  4 <named list [18]>
#>  5 <named list [18]>
#>  6 <named list [18]>
#>  7 <named list [18]>
#>  8 <named list [18]>
#>  9 <named list [18]>
#> 10 <named list [18]>
#> # … with 20 more rows

chars2 <- chars %>% unnest_wider(char)
chars2
#> # A tibble: 30 x 18
#>    url      id name  gender culture born  died  alive titles aliases father
#>    <chr> <int> <chr> <chr>  <chr>   <chr> <chr> <lgl> <list> <list>  <chr> 
#>  1 http…  1022 Theo… Male   Ironbo… In 2… ""    TRUE  <chr … <chr [… ""    
#>  2 http…  1052 Tyri… Male   ""      In 2… ""    TRUE  <chr … <chr [… ""    
#>  3 http…  1074 Vict… Male   Ironbo… In 2… ""    TRUE  <chr … <chr [… ""    
#>  4 http…  1109 Will  Male   ""      ""    In 2… FALSE <chr … <chr [… ""    
#>  5 http…  1166 Areo… Male   Norvos… In 2… ""    TRUE  <chr … <chr [… ""    
#>  6 http…  1267 Chett Male   ""      At H… In 2… FALSE <chr … <chr [… ""    
#>  7 http…  1295 Cres… Male   ""      In 2… In 2… FALSE <chr … <chr [… ""    
#>  8 http…   130 Aria… Female Dornish In 2… ""    TRUE  <chr … <chr [… ""    
#>  9 http…  1303 Daen… Female Valyri… In 2… ""    TRUE  <chr … <chr [… ""    
#> 10 http…  1319 Davo… Male   Wester… In 2… ""    TRUE  <chr … <chr [… ""    
#> # … with 20 more rows, and 7 more variables: mother <chr>, spouse <chr>,
#> #   allegiances <list>, books <list>, povBooks <list>, tvSeries <list>,
#> #   playedBy <list>

Δομή got_chars κάπως πιο δύσκολο από gh_users, επειδή ορισμένα στοιχεία λίστας char οι ίδιοι είναι μια λίστα, με αποτέλεσμα να έχουμε πυλώνες - λίστες:

chars2 %>% select_if(is.list)
#> # A tibble: 30 x 7
#>    titles    aliases    allegiances books     povBooks  tvSeries  playedBy 
#>    <list>    <list>     <list>      <list>    <list>    <list>    <list>   
#>  1 <chr [3]> <chr [4]>  <chr [1]>   <chr [3]> <chr [2]> <chr [6]> <chr [1]>
#>  2 <chr [2]> <chr [11]> <chr [1]>   <chr [2]> <chr [4]> <chr [6]> <chr [1]>
#>  3 <chr [2]> <chr [1]>  <chr [1]>   <chr [3]> <chr [2]> <chr [1]> <chr [1]>
#>  4 <chr [1]> <chr [1]>  <???>       <chr [1]> <chr [1]> <chr [1]> <chr [1]>
#>  5 <chr [1]> <chr [1]>  <chr [1]>   <chr [3]> <chr [2]> <chr [2]> <chr [1]>
#>  6 <chr [1]> <chr [1]>  <???>       <chr [2]> <chr [1]> <chr [1]> <chr [1]>
#>  7 <chr [1]> <chr [1]>  <???>       <chr [2]> <chr [1]> <chr [1]> <chr [1]>
#>  8 <chr [1]> <chr [1]>  <chr [1]>   <chr [4]> <chr [1]> <chr [1]> <chr [1]>
#>  9 <chr [5]> <chr [11]> <chr [1]>   <chr [1]> <chr [4]> <chr [6]> <chr [1]>
#> 10 <chr [4]> <chr [5]>  <chr [2]>   <chr [1]> <chr [3]> <chr [5]> <chr [1]>
#> # … with 20 more rows

Οι περαιτέρω ενέργειές σας εξαρτώνται από τους στόχους της ανάλυσης. Ίσως πρέπει να βάλετε πληροφορίες στις γραμμές για κάθε βιβλίο και σειρά στην οποία εμφανίζεται ο χαρακτήρας:

chars2 %>% 
  select(name, books, tvSeries) %>% 
  pivot_longer(c(books, tvSeries), names_to = "media", values_to = "value") %>% 
  unnest_longer(value)
#> # A tibble: 180 x 3
#>    name             media    value            
#>    <chr>            <chr>    <chr>            
#>  1 Theon Greyjoy    books    A Game of Thrones
#>  2 Theon Greyjoy    books    A Storm of Swords
#>  3 Theon Greyjoy    books    A Feast for Crows
#>  4 Theon Greyjoy    tvSeries Season 1         
#>  5 Theon Greyjoy    tvSeries Season 2         
#>  6 Theon Greyjoy    tvSeries Season 3         
#>  7 Theon Greyjoy    tvSeries Season 4         
#>  8 Theon Greyjoy    tvSeries Season 5         
#>  9 Theon Greyjoy    tvSeries Season 6         
#> 10 Tyrion Lannister books    A Feast for Crows
#> # … with 170 more rows

Ή ίσως θέλετε να δημιουργήσετε έναν πίνακα που σας επιτρέπει να ταιριάξετε τον χαρακτήρα και το έργο:

chars2 %>% 
  select(name, title = titles) %>% 
  unnest_longer(title)
#> # A tibble: 60 x 2
#>    name              title                                               
#>    <chr>             <chr>                                               
#>  1 Theon Greyjoy     Prince of Winterfell                                
#>  2 Theon Greyjoy     Captain of Sea Bitch                                
#>  3 Theon Greyjoy     Lord of the Iron Islands (by law of the green lands)
#>  4 Tyrion Lannister  Acting Hand of the King (former)                    
#>  5 Tyrion Lannister  Master of Coin (former)                             
#>  6 Victarion Greyjoy Lord Captain of the Iron Fleet                      
#>  7 Victarion Greyjoy Master of the Iron Victory                          
#>  8 Will              ""                                                  
#>  9 Areo Hotah        Captain of the Guard at Sunspear                    
#> 10 Chett             ""                                                  
#> # … with 50 more rows

(Σημειώστε τις κενές τιμές "" στον τομέα title, αυτό οφείλεται σε σφάλματα που έγιναν κατά την εισαγωγή δεδομένων got_chars: μάλιστα χαρακτήρες για τους οποίους δεν υπάρχουν αντίστοιχοι τίτλοι βιβλίων και τηλεοπτικών σειρών στο πεδίο title πρέπει να έχει διάνυσμα μήκους 0, όχι διάνυσμα μήκους 1 που περιέχει την κενή συμβολοσειρά.)

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

tibble(char = got_chars) %>% 
  unnest_auto(char) %>% 
  select(name, title = titles) %>% 
  unnest_auto(title)
#> Using `unnest_wider(char)`; elements have 18 names in common
#> Using `unnest_longer(title)`; no element has names
#> # A tibble: 60 x 2
#>    name              title                                               
#>    <chr>             <chr>                                               
#>  1 Theon Greyjoy     Prince of Winterfell                                
#>  2 Theon Greyjoy     Captain of Sea Bitch                                
#>  3 Theon Greyjoy     Lord of the Iron Islands (by law of the green lands)
#>  4 Tyrion Lannister  Acting Hand of the King (former)                    
#>  5 Tyrion Lannister  Master of Coin (former)                             
#>  6 Victarion Greyjoy Lord Captain of the Iron Fleet                      
#>  7 Victarion Greyjoy Master of the Iron Victory                          
#>  8 Will              ""                                                  
#>  9 Areo Hotah        Captain of the Guard at Sunspear                    
#> 10 Chett             ""                                                  
#> # … with 50 more rows

Γεωκωδικοποίηση με το Google

Στη συνέχεια, θα εξετάσουμε μια πιο περίπλοκη δομή των δεδομένων που λαμβάνονται από την υπηρεσία γεωκωδικοποίησης της Google. Η αποθήκευση διαπιστευτηρίων στην προσωρινή μνήμη είναι αντίθετη με τους κανόνες εργασίας με το API χαρτών Google, επομένως θα γράψω πρώτα ένα απλό περιτύλιγμα γύρω από το API. Το οποίο βασίζεται στην αποθήκευση του κλειδιού API Χαρτών Google σε μια μεταβλητή περιβάλλοντος. Εάν δεν έχετε το κλειδί για εργασία με το API των Χαρτών Google αποθηκευμένο στις μεταβλητές περιβάλλοντος, τα τμήματα κώδικα που παρουσιάζονται σε αυτήν την ενότητα δεν θα εκτελεστούν.

has_key <- !identical(Sys.getenv("GOOGLE_MAPS_API_KEY"), "")
if (!has_key) {
  message("No Google Maps API key found; code chunks will not be run")
}

# https://developers.google.com/maps/documentation/geocoding
geocode <- function(address, api_key = Sys.getenv("GOOGLE_MAPS_API_KEY")) {
  url <- "https://maps.googleapis.com/maps/api/geocode/json"
  url <- paste0(url, "?address=", URLencode(address), "&key=", api_key)

  jsonlite::read_json(url)
}

Η λίστα που επιστρέφει αυτή η συνάρτηση είναι αρκετά περίπλοκη:

houston <- geocode("Houston TX")
str(houston)
#> List of 2
#>  $ results:List of 1
#>   ..$ :List of 5
#>   .. ..$ address_components:List of 4
#>   .. .. ..$ :List of 3
#>   .. .. .. ..$ long_name : chr "Houston"
#>   .. .. .. ..$ short_name: chr "Houston"
#>   .. .. .. ..$ types     :List of 2
#>   .. .. .. .. ..$ : chr "locality"
#>   .. .. .. .. ..$ : chr "political"
#>   .. .. ..$ :List of 3
#>   .. .. .. ..$ long_name : chr "Harris County"
#>   .. .. .. ..$ short_name: chr "Harris County"
#>   .. .. .. ..$ types     :List of 2
#>   .. .. .. .. ..$ : chr "administrative_area_level_2"
#>   .. .. .. .. ..$ : chr "political"
#>   .. .. ..$ :List of 3
#>   .. .. .. ..$ long_name : chr "Texas"
#>   .. .. .. ..$ short_name: chr "TX"
#>   .. .. .. ..$ types     :List of 2
#>   .. .. .. .. ..$ : chr "administrative_area_level_1"
#>   .. .. .. .. ..$ : chr "political"
#>   .. .. ..$ :List of 3
#>   .. .. .. ..$ long_name : chr "United States"
#>   .. .. .. ..$ short_name: chr "US"
#>   .. .. .. ..$ types     :List of 2
#>   .. .. .. .. ..$ : chr "country"
#>   .. .. .. .. ..$ : chr "political"
#>   .. ..$ formatted_address : chr "Houston, TX, USA"
#>   .. ..$ geometry          :List of 4
#>   .. .. ..$ bounds       :List of 2
#>   .. .. .. ..$ northeast:List of 2
#>   .. .. .. .. ..$ lat: num 30.1
#>   .. .. .. .. ..$ lng: num -95
#>   .. .. .. ..$ southwest:List of 2
#>   .. .. .. .. ..$ lat: num 29.5
#>   .. .. .. .. ..$ lng: num -95.8
#>   .. .. ..$ location     :List of 2
#>   .. .. .. ..$ lat: num 29.8
#>   .. .. .. ..$ lng: num -95.4
#>   .. .. ..$ location_type: chr "APPROXIMATE"
#>   .. .. ..$ viewport     :List of 2
#>   .. .. .. ..$ northeast:List of 2
#>   .. .. .. .. ..$ lat: num 30.1
#>   .. .. .. .. ..$ lng: num -95
#>   .. .. .. ..$ southwest:List of 2
#>   .. .. .. .. ..$ lat: num 29.5
#>   .. .. .. .. ..$ lng: num -95.8
#>   .. ..$ place_id          : chr "ChIJAYWNSLS4QIYROwVl894CDco"
#>   .. ..$ types             :List of 2
#>   .. .. ..$ : chr "locality"
#>   .. .. ..$ : chr "political"
#>  $ status : chr "OK"

Ευτυχώς, μπορούμε να λύσουμε το πρόβλημα της μετατροπής αυτών των δεδομένων σε μορφή πίνακα βήμα προς βήμα χρησιμοποιώντας συναρτήσεις tidyr. Για να κάνω την εργασία λίγο πιο προκλητική και ρεαλιστική, θα ξεκινήσω με γεωκωδικοποίηση μερικών πόλεων:

  city <-   c ( "Houston" , "LA" , "New York" , "Chicago" , "Springfield" )  city_geo <-   purrr::map (city, geocode) 

Θα μετατρέψω το αποτέλεσμα που προκύπτει σε tibble, για διευκόλυνση, θα προσθέσω μια στήλη με το αντίστοιχο όνομα πόλης.

loc <- tibble(city = city, json = city_geo)
loc
#> # A tibble: 5 x 2
#>   city        json            
#>   <chr>       <list>          
#> 1 Houston     <named list [2]>
#> 2 LA          <named list [2]>
#> 3 New York    <named list [2]>
#> 4 Chicago     <named list [2]>
#> 5 Springfield <named list [2]>

Το πρώτο επίπεδο περιέχει στοιχεία status и result, με το οποίο μπορούμε να επεκτείνουμε unnest_wider() :

loc %>%
  unnest_wider(json)
#> # A tibble: 5 x 3
#>   city        results    status
#>   <chr>       <list>     <chr> 
#> 1 Houston     <list [1]> OK    
#> 2 LA          <list [1]> OK    
#> 3 New York    <list [1]> OK    
#> 4 Chicago     <list [1]> OK    
#> 5 Springfield <list [1]> OK

Σημειώστε ότι results είναι μια λίστα πολλαπλών επιπέδων. Οι περισσότερες πόλεις έχουν 1 στοιχείο (που αντιπροσωπεύει μια μοναδική τιμή που αντιστοιχεί στο API γεωκωδικοποίησης), αλλά το Springfield έχει δύο. Μπορούμε να τα τραβήξουμε σε ξεχωριστές γραμμές με unnest_longer() :

loc %>%
  unnest_wider(json) %>% 
  unnest_longer(results)
#> # A tibble: 5 x 3
#>   city        results          status
#>   <chr>       <list>           <chr> 
#> 1 Houston     <named list [5]> OK    
#> 2 LA          <named list [5]> OK    
#> 3 New York    <named list [5]> OK    
#> 4 Chicago     <named list [5]> OK    
#> 5 Springfield <named list [5]> OK

Τώρα έχουν όλα τα ίδια εξαρτήματα, τα οποία μπορούν να επαληθευτούν χρησιμοποιώντας unnest_wider():

loc %>%
  unnest_wider(json) %>% 
  unnest_longer(results) %>% 
  unnest_wider(results)
#> # A tibble: 5 x 7
#>   city   address_componen… formatted_addre… geometry place_id  types status
#>   <chr>  <list>            <chr>            <list>   <chr>     <lis> <chr> 
#> 1 Houst… <list [4]>        Houston, TX, USA <named … ChIJAYWN… <lis… OK    
#> 2 LA     <list [4]>        Los Angeles, CA… <named … ChIJE9on… <lis… OK    
#> 3 New Y… <list [3]>        New York, NY, U… <named … ChIJOwg_… <lis… OK    
#> 4 Chica… <list [4]>        Chicago, IL, USA <named … ChIJ7cv0… <lis… OK    
#> 5 Sprin… <list [5]>        Springfield, MO… <named … ChIJP5jI… <lis… OK

Μπορούμε να βρούμε τις συντεταγμένες γεωγραφικού πλάτους και μήκους κάθε πόλης επεκτείνοντας τη λίστα geometry:

loc %>%
  unnest_wider(json) %>% 
  unnest_longer(results) %>% 
  unnest_wider(results) %>% 
  unnest_wider(geometry)
#> # A tibble: 5 x 10
#>   city  address_compone… formatted_addre… bounds location location_type
#>   <chr> <list>           <chr>            <list> <list>   <chr>        
#> 1 Hous… <list [4]>       Houston, TX, USA <name… <named … APPROXIMATE  
#> 2 LA    <list [4]>       Los Angeles, CA… <name… <named … APPROXIMATE  
#> 3 New … <list [3]>       New York, NY, U… <name… <named … APPROXIMATE  
#> 4 Chic… <list [4]>       Chicago, IL, USA <name… <named … APPROXIMATE  
#> 5 Spri… <list [5]>       Springfield, MO… <name… <named … APPROXIMATE  
#> # … with 4 more variables: viewport <list>, place_id <chr>, types <list>,
#> #   status <chr>

Και μετά η τοποθεσία για την οποία πρέπει να επεκταθείτε location:

loc %>%
  unnest_wider(json) %>%
  unnest_longer(results) %>%
  unnest_wider(results) %>%
  unnest_wider(geometry) %>%
  unnest_wider(location)
#> # A tibble: 5 x 11
#>   city  address_compone… formatted_addre… bounds   lat    lng location_type
#>   <chr> <list>           <chr>            <list> <dbl>  <dbl> <chr>        
#> 1 Hous… <list [4]>       Houston, TX, USA <name…  29.8  -95.4 APPROXIMATE  
#> 2 LA    <list [4]>       Los Angeles, CA… <name…  34.1 -118.  APPROXIMATE  
#> 3 New … <list [3]>       New York, NY, U… <name…  40.7  -74.0 APPROXIMATE  
#> 4 Chic… <list [4]>       Chicago, IL, USA <name…  41.9  -87.6 APPROXIMATE  
#> 5 Spri… <list [5]>       Springfield, MO… <name…  37.2  -93.3 APPROXIMATE  
#> # … with 4 more variables: viewport <list>, place_id <chr>, types <list>,
#> #   status <chr>

Για άλλη μία φορά, unnest_auto() απλοποιεί την περιγραφόμενη λειτουργία με ορισμένους κινδύνους που μπορεί να προκληθούν από την αλλαγή της δομής των εισερχόμενων δεδομένων:

loc %>%
  unnest_auto(json) %>%
  unnest_auto(results) %>%
  unnest_auto(results) %>%
  unnest_auto(geometry) %>%
  unnest_auto(location)
#> Using `unnest_wider(json)`; elements have 2 names in common
#> Using `unnest_longer(results)`; no element has names
#> Using `unnest_wider(results)`; elements have 5 names in common
#> Using `unnest_wider(geometry)`; elements have 4 names in common
#> Using `unnest_wider(location)`; elements have 2 names in common
#> # A tibble: 5 x 11
#>   city  address_compone… formatted_addre… bounds   lat    lng location_type
#>   <chr> <list>           <chr>            <list> <dbl>  <dbl> <chr>        
#> 1 Hous… <list [4]>       Houston, TX, USA <name…  29.8  -95.4 APPROXIMATE  
#> 2 LA    <list [4]>       Los Angeles, CA… <name…  34.1 -118.  APPROXIMATE  
#> 3 New … <list [3]>       New York, NY, U… <name…  40.7  -74.0 APPROXIMATE  
#> 4 Chic… <list [4]>       Chicago, IL, USA <name…  41.9  -87.6 APPROXIMATE  
#> 5 Spri… <list [5]>       Springfield, MO… <name…  37.2  -93.3 APPROXIMATE  
#> # … with 4 more variables: viewport <list>, place_id <chr>, types <list>,
#> #   status <chr>

Μπορούμε επίσης να δούμε την πρώτη διεύθυνση για κάθε πόλη:

loc %>%
  unnest_wider(json) %>%
  hoist(results, first_result = 1) %>%
  unnest_wider(first_result) %>%
  unnest_wider(geometry) %>%
  unnest_wider(location)
#> # A tibble: 5 x 11
#>   city  address_compone… formatted_addre… bounds   lat    lng location_type
#>   <chr> <list>           <chr>            <list> <dbl>  <dbl> <chr>        
#> 1 Hous… <list [4]>       Houston, TX, USA <name…  29.8  -95.4 APPROXIMATE  
#> 2 LA    <list [4]>       Los Angeles, CA… <name…  34.1 -118.  APPROXIMATE  
#> 3 New … <list [3]>       New York, NY, U… <name…  40.7  -74.0 APPROXIMATE  
#> 4 Chic… <list [4]>       Chicago, IL, USA <name…  41.9  -87.6 APPROXIMATE  
#> 5 Spri… <list [5]>       Springfield, MO… <name…  37.2  -93.3 APPROXIMATE  
#> # … with 4 more variables: viewport <list>, place_id <chr>, types <list>,
#> #   status <chr>

Ή χρησιμοποιήστε hoist() για μια κατάδυση πολλαπλών επιπέδων για να μεταβείτε απευθείας lat и lng.

loc %>%
  hoist(json,
    lat = list("results", 1, "geometry", "location", "lat"),
    lng = list("results", 1, "geometry", "location", "lng")
  )
#> # A tibble: 5 x 4
#>   city          lat    lng json            
#>   <chr>       <dbl>  <dbl> <list>          
#> 1 Houston      29.8  -95.4 <named list [2]>
#> 2 LA           34.1 -118.  <named list [2]>
#> 3 New York     40.7  -74.0 <named list [2]>
#> 4 Chicago      41.9  -87.6 <named list [2]>
#> 5 Springfield  37.2  -93.3 <named list [2]>

Δισκογραφία Sharla Gelfand

Τέλος, θα δούμε την πιο περίπλοκη δομή - τη δισκογραφία της Sharla Gelfand. Όπως στα παραπάνω παραδείγματα, ξεκινάμε μετατρέποντας τη λίστα σε πλαίσιο δεδομένων μίας στήλης και, στη συνέχεια, την επεκτείνουμε έτσι ώστε κάθε στοιχείο να είναι μια ξεχωριστή στήλη. Επίσης μεταμορφώνω τη στήλη date_added στην κατάλληλη μορφή ημερομηνίας και ώρας στο R.

discs <- tibble(disc = discog) %>% 
  unnest_wider(disc) %>% 
  mutate(date_added = as.POSIXct(strptime(date_added, "%Y-%m-%dT%H:%M:%S"))) 
discs
#> # A tibble: 155 x 5
#>    instance_id date_added          basic_information       id rating
#>          <int> <dttm>              <list>               <int>  <int>
#>  1   354823933 2019-02-16 17:48:59 <named list [11]>  7496378      0
#>  2   354092601 2019-02-13 14:13:11 <named list [11]>  4490852      0
#>  3   354091476 2019-02-13 14:07:23 <named list [11]>  9827276      0
#>  4   351244906 2019-02-02 11:39:58 <named list [11]>  9769203      0
#>  5   351244801 2019-02-02 11:39:37 <named list [11]>  7237138      0
#>  6   351052065 2019-02-01 20:40:53 <named list [11]> 13117042      0
#>  7   350315345 2019-01-29 15:48:37 <named list [11]>  7113575      0
#>  8   350315103 2019-01-29 15:47:22 <named list [11]> 10540713      0
#>  9   350314507 2019-01-29 15:44:08 <named list [11]> 11260950      0
#> 10   350314047 2019-01-29 15:41:35 <named list [11]> 11726853      0
#> # … with 145 more rows

Σε αυτό το επίπεδο, λαμβάνουμε πληροφορίες για το πότε προστέθηκε κάθε δίσκος στη δισκογραφία της Sharla, αλλά δεν βλέπουμε δεδομένα σχετικά με αυτούς τους δίσκους. Για να γίνει αυτό πρέπει να επεκτείνουμε τη στήλη basic_information:

discs %>% unnest_wider(basic_information)
#> Column name `id` must not be duplicated.
#> Use .name_repair to specify repair.

Δυστυχώς, θα λάβουμε ένα σφάλμα, επειδή... μέσα στη λίστα basic_information υπάρχει μια στήλη με το ίδιο όνομα basic_information. Εάν παρουσιαστεί ένα τέτοιο σφάλμα, για να προσδιορίσετε γρήγορα την αιτία του, μπορείτε να χρησιμοποιήσετε names_repair = "unique":

discs %>% unnest_wider(basic_information, names_repair = "unique")
#> New names:
#> * id -> id...6
#> * id -> id...14
#> # A tibble: 155 x 15
#>    instance_id date_added          labels  year artists id...6 thumb title
#>          <int> <dttm>              <list> <int> <list>   <int> <chr> <chr>
#>  1   354823933 2019-02-16 17:48:59 <list…  2015 <list … 7.50e6 http… Demo 
#>  2   354092601 2019-02-13 14:13:11 <list…  2013 <list … 4.49e6 http… Obse…
#>  3   354091476 2019-02-13 14:07:23 <list…  2017 <list … 9.83e6 http… I    
#>  4   351244906 2019-02-02 11:39:58 <list…  2017 <list … 9.77e6 http… Oído…
#>  5   351244801 2019-02-02 11:39:37 <list…  2015 <list … 7.24e6 http… A Ca…
#>  6   351052065 2019-02-01 20:40:53 <list…  2019 <list … 1.31e7 http… Tash…
#>  7   350315345 2019-01-29 15:48:37 <list…  2014 <list … 7.11e6 http… Demo 
#>  8   350315103 2019-01-29 15:47:22 <list…  2015 <list … 1.05e7 http… Let …
#>  9   350314507 2019-01-29 15:44:08 <list…  2017 <list … 1.13e7 ""    Sub …
#> 10   350314047 2019-01-29 15:41:35 <list…  2017 <list … 1.17e7 http… Demo 
#> # … with 145 more rows, and 7 more variables: formats <list>,
#> #   cover_image <chr>, resource_url <chr>, master_id <int>,
#> #   master_url <chr>, id...14 <int>, rating <int>

Το πρόβλημα είναι ότι basic_information επαναλαμβάνει τη στήλη id που είναι επίσης αποθηκευμένη στο ανώτερο επίπεδο, ώστε να μπορούμε απλά να την αφαιρέσουμε:

discs %>% 
  select(-id) %>% 
  unnest_wider(basic_information)
#> # A tibble: 155 x 14
#>    instance_id date_added          labels  year artists     id thumb title
#>          <int> <dttm>              <list> <int> <list>   <int> <chr> <chr>
#>  1   354823933 2019-02-16 17:48:59 <list…  2015 <list … 7.50e6 http… Demo 
#>  2   354092601 2019-02-13 14:13:11 <list…  2013 <list … 4.49e6 http… Obse…
#>  3   354091476 2019-02-13 14:07:23 <list…  2017 <list … 9.83e6 http… I    
#>  4   351244906 2019-02-02 11:39:58 <list…  2017 <list … 9.77e6 http… Oído…
#>  5   351244801 2019-02-02 11:39:37 <list…  2015 <list … 7.24e6 http… A Ca…
#>  6   351052065 2019-02-01 20:40:53 <list…  2019 <list … 1.31e7 http… Tash…
#>  7   350315345 2019-01-29 15:48:37 <list…  2014 <list … 7.11e6 http… Demo 
#>  8   350315103 2019-01-29 15:47:22 <list…  2015 <list … 1.05e7 http… Let …
#>  9   350314507 2019-01-29 15:44:08 <list…  2017 <list … 1.13e7 ""    Sub …
#> 10   350314047 2019-01-29 15:41:35 <list…  2017 <list … 1.17e7 http… Demo 
#> # … with 145 more rows, and 6 more variables: formats <list>,
#> #   cover_image <chr>, resource_url <chr>, master_id <int>,
#> #   master_url <chr>, rating <int>

Εναλλακτικά, θα μπορούσαμε να χρησιμοποιήσουμε hoist():

discs %>% 
  hoist(basic_information,
    title = "title",
    year = "year",
    label = list("labels", 1, "name"),
    artist = list("artists", 1, "name")
  )
#> # A tibble: 155 x 9
#>    instance_id date_added          title  year label artist
#>          <int> <dttm>              <chr> <int> <chr> <chr> 
#>  1   354823933 2019-02-16 17:48:59 Demo   2015 Tobi… Mollot
#>  2   354092601 2019-02-13 14:13:11 Obse…  2013 La V… Una B…
#>  3   354091476 2019-02-13 14:07:23 I      2017 La V… S.H.I…
#>  4   351244906 2019-02-02 11:39:58 Oído…  2017 La V… Rata …
#>  5   351244801 2019-02-02 11:39:37 A Ca…  2015 Kato… Ivy (…
#>  6   351052065 2019-02-01 20:40:53 Tash…  2019 High… Tashme
#>  7   350315345 2019-01-29 15:48:37 Demo   2014 Mind… Desgr…
#>  8   350315103 2019-01-29 15:47:22 Let …  2015 Not … Phant…
#>  9   350314507 2019-01-29 15:44:08 Sub …  2017 Not … Sub S…
#> 10   350314047 2019-01-29 15:41:35 Demo   2017 Pres… Small…
#> # … with 145 more rows, and 3 more variables: basic_information <list>,
#> #   id <int>, rating <int>

Εδώ ανακτώ γρήγορα την πρώτη ετικέτα και το όνομα του καλλιτέχνη ανά ευρετήριο, βουτώντας στην ένθετη λίστα.

Μια πιο συστηματική προσέγγιση είναι η δημιουργία χωριστών πινάκων για καλλιτέχνη και ετικέτα:

discs %>% 
  hoist(basic_information, artist = "artists") %>% 
  select(disc_id = id, artist) %>% 
  unnest_longer(artist) %>% 
  unnest_wider(artist)
#> # A tibble: 167 x 8
#>     disc_id join  name        anv   tracks role  resource_url            id
#>       <int> <chr> <chr>       <chr> <chr>  <chr> <chr>                <int>
#>  1  7496378 ""    Mollot      ""    ""     ""    https://api.discog… 4.62e6
#>  2  4490852 ""    Una Bèstia… ""    ""     ""    https://api.discog… 3.19e6
#>  3  9827276 ""    S.H.I.T. (… ""    ""     ""    https://api.discog… 2.77e6
#>  4  9769203 ""    Rata Negra  ""    ""     ""    https://api.discog… 4.28e6
#>  5  7237138 ""    Ivy (18)    ""    ""     ""    https://api.discog… 3.60e6
#>  6 13117042 ""    Tashme      ""    ""     ""    https://api.discog… 5.21e6
#>  7  7113575 ""    Desgraciad… ""    ""     ""    https://api.discog… 4.45e6
#>  8 10540713 ""    Phantom He… ""    ""     ""    https://api.discog… 4.27e6
#>  9 11260950 ""    Sub Space … ""    ""     ""    https://api.discog… 5.69e6
#> 10 11726853 ""    Small Man … ""    ""     ""    https://api.discog… 6.37e6
#> # … with 157 more rows

discs %>% 
  hoist(basic_information, format = "formats") %>% 
  select(disc_id = id, format) %>% 
  unnest_longer(format) %>% 
  unnest_wider(format) %>% 
  unnest_longer(descriptions)
#> # A tibble: 280 x 5
#>     disc_id descriptions text  name     qty  
#>       <int> <chr>        <chr> <chr>    <chr>
#>  1  7496378 Numbered     Black Cassette 1    
#>  2  4490852 LP           <NA>  Vinyl    1    
#>  3  9827276 "7""        <NA>  Vinyl    1    
#>  4  9827276 45 RPM       <NA>  Vinyl    1    
#>  5  9827276 EP           <NA>  Vinyl    1    
#>  6  9769203 LP           <NA>  Vinyl    1    
#>  7  9769203 Album        <NA>  Vinyl    1    
#>  8  7237138 "7""        <NA>  Vinyl    1    
#>  9  7237138 45 RPM       <NA>  Vinyl    1    
#> 10 13117042 "7""        <NA>  Vinyl    1    
#> # … with 270 more rows

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

Συμπέρασμα

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

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

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο