ProHoster > blog > administratie > Geneste kolommen uitbreiden - lijsten met behulp van de R-taal (tidyr-pakket en functies van de unnest-familie)
Geneste kolommen uitbreiden - lijsten met behulp van de R-taal (tidyr-pakket en functies van de unnest-familie)
Wanneer u werkt met een antwoord dat is ontvangen van een API, of met andere gegevens met een complexe boomstructuur, wordt u in de meeste gevallen geconfronteerd met JSON- en XML-formaten.
Deze formaten hebben veel voordelen: ze slaan gegevens vrij compact op en zorgen ervoor dat u onnodige duplicatie van informatie voorkomt.
Het nadeel van deze formaten is de complexiteit van hun verwerking en analyse. Ongestructureerde gegevens kunnen niet worden gebruikt in berekeningen en er kan niet op worden voortgebouwd.
Dit artikel is een logisch vervolg op de publicatie "R-pakket Tidr en zijn nieuwe functies pivot_longer en pivot_wider". Het zal u helpen ongestructureerde datastructuren met behulp van het pakket in een vertrouwde en voor analyse geschikte tabelvorm om te zetten tidyr, opgenomen in de kern van de bibliotheek tidyverse, en zijn familie van functies unnest_*().
Inhoud
Als u geïnteresseerd bent in data-analyse, bent u wellicht geïnteresseerd in mijn telegram и youtube kanalen. Het grootste deel van de inhoud is gewijd aan de R-taal.
Rechthoekig(Opmerking van de vertaler: ik heb geen adequate vertaalopties gevonden voor deze term, dus laten we het zoals het is.) is het proces waarbij ongestructureerde gegevens met geneste arrays in een tweedimensionale tabel worden gebracht die bestaat uit bekende rijen en kolommen. IN tidyr Er zijn verschillende functies waarmee u geneste lijstkolommen kunt uitbreiden en de gegevens kunt terugbrengen tot een rechthoekige tabelvorm:
unnest_longer() neemt elk element van de kolomlijst en maakt een nieuwe rij.
unnest_wider() neemt elk element van de kolomlijst en maakt een nieuwe kolom.
unnest_auto() bepaalt automatisch welke functie het beste kan worden gebruikt unnest_longer() of unnest_wider().
hoist() gelijkwaardig aan unnest_wider() maar selecteert alleen de opgegeven componenten en stelt u in staat met verschillende nestingniveaus te werken.
De meeste problemen die gepaard gaan met het samenbrengen van ongestructureerde gegevens met verschillende nestniveaus in een tweedimensionale tabel kunnen worden opgelost door de vermelde functies te combineren met dplyr.
Om deze technieken te demonstreren, zullen we het pakket gebruiken repurrrsive, dat meerdere complexe lijsten met meerdere niveaus biedt, afgeleid van een web-API.
Laten we beginnen gh_gebruikers, een lijst met informatie over zes GitHub-gebruikers. Laten we eerst de lijst transformeren gh_gebruikers в gebabbel kader:
users <- tibble( user = gh_users )
Dit lijkt een beetje contra-intuïtief: waarom zou u een lijst verstrekken? gh_gebruikers, naar een complexere datastructuur? Maar een dataframe heeft een groot voordeel: het combineert meerdere vectoren zodat alles in één object wordt gevolgd.
Elk objectelement users is een benoemde lijst waarin elk element een kolom vertegenwoordigt.
In dit geval hebben we een tabel die uit 30 kolommen bestaat, en we zullen de meeste daarvan niet nodig hebben, dus we kunnen in plaats daarvan unnest_wider() te gebruiken hoist(). hoist() stelt ons in staat geselecteerde componenten te extraheren met dezelfde syntaxis als 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() verwijdert de opgegeven benoemde componenten uit een kolommenlijst gebruikerzodat je kunt overwegen hoist() zoals het verplaatsen van componenten van de interne lijst van een datumframe naar het hoogste niveau.
Github-opslagplaatsen
Lijstuitlijning gh_repos we beginnen op dezelfde manier door het om te zetten naar tibble:
Dit keer de elementen gebruiker vertegenwoordigen een lijst met opslagplaatsen die eigendom zijn van deze gebruiker. Elke repository is een aparte observatie, dus volgens het concept van ‘nette data’ (ong. nette gegevens) het zouden nieuwe lijnen moeten worden, daarom gebruiken we unnest_longer() en niet 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
Nu kunnen we gebruiken unnest_wider() of 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
Let op het gebruik c("owner", "login"): Hierdoor kunnen we de waarde op het tweede niveau uit een geneste lijst halen owner. Een alternatieve benadering is om de volledige lijst te verkrijgen owner en vervolgens de functie gebruiken unnest_wider() plaats elk van de elementen in een kolom:
In plaats van na te denken over het kiezen van de juiste functie unnest_longer() of unnest_wider() je kunt gebruiken unnest_auto(). Deze functie gebruikt verschillende heuristische methoden om de meest geschikte functie voor het transformeren van de gegevens te selecteren, en geeft een bericht weer over de gekozen methode.
got_chars heeft een identieke structuur als gh_users: Dit is een reeks benoemde lijsten, waarbij elk element van de binnenste lijst een kenmerk van een Game of Thrones-personage beschrijft. Brengen got_chars Voor de tabelweergave beginnen we met het maken van een datumframe, net als in de vorige voorbeelden, en converteren we vervolgens elk element naar een afzonderlijke kolom:
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>
Structuur got_chars iets moeilijker dan gh_users, omdat enkele lijstcomponenten char zelf zijn een lijst, als resultaat krijgen we pijlers - lijsten:
Uw verdere acties zijn afhankelijk van de doelstellingen van de analyse. Misschien moet je informatie over de regels plaatsen voor elk boek en elke serie waarin het personage verschijnt:
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
Of misschien wil je een tafel maken waarmee je het personage en het werk op elkaar kunt afstemmen:
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
(Let op de lege waarden "" in het veld title, dit komt door fouten die zijn gemaakt bij het invoeren van gegevens in got_chars: in feite personages waarvoor er geen overeenkomstige titels van boeken en tv-series in het veld bestaan title moet een vector met lengte 0 hebben, niet een vector met lengte 1 die de lege string bevat.)
We kunnen het bovenstaande voorbeeld herschrijven met behulp van de functie unnest_auto(). Deze aanpak is handig voor eenmalige analyse, maar u moet er niet op vertrouwen unnest_auto() voor regelmatig gebruik. Het punt is dat als uw datastructuur verandert unnest_auto() kan het geselecteerde gegevenstransformatiemechanisme wijzigen als het aanvankelijk lijstkolommen in rijen uitbreidde met behulp van unnest_longer()Wanneer de structuur van de binnenkomende gegevens verandert, kan de logica ten gunste worden veranderd unnest_wider(), en het voortdurend gebruiken van deze aanpak kan tot onverwachte fouten leiden.
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
Geocodering met Google
Vervolgens bekijken we een complexere structuur van de gegevens die zijn verkregen via de geocoderingsservice van Google. Het cachen van inloggegevens is in strijd met de regels van het werken met de Google Maps API, dus ik zal eerst een eenvoudige verpakking rond de API schrijven. Die is gebaseerd op het opslaan van de Google Maps API-sleutel in een omgevingsvariabele; Als u niet beschikt over de sleutel voor het werken met de Google Maps API die is opgeslagen in uw omgevingsvariabelen, worden de codefragmenten die in deze sectie worden gepresenteerd, niet uitgevoerd.
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)
}
De lijst die deze functie retourneert is behoorlijk complex:
Gelukkig kunnen we het probleem van het omzetten van deze gegevens in tabelvorm stap voor stap oplossen met behulp van functies tidyr. Om de taak wat uitdagender en realistischer te maken, begin ik met het geocoderen van een paar steden:
city <- c ( "Houston" , "LA" , "New York" , "Chicago" , "Springfield" ) city_geo <- purrr::map (city, geocode)
Het resulterende resultaat zal ik omzetten in tibbleVoor het gemak zal ik een kolom toevoegen met de bijbehorende stadsnaam.
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]>
Het eerste niveau bevat componenten status и result, waarmee we kunnen uitbreiden 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
Houd er rekening mee dat results is een lijst met meerdere niveaus. De meeste steden hebben één element (dat een unieke waarde vertegenwoordigt die overeenkomt met de geocodering-API), maar Springfield heeft er twee. We kunnen ze in afzonderlijke lijnen samenbrengen 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
Nu hebben ze allemaal dezelfde componenten, die kunnen worden geverifieerd met behulp van 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
We kunnen de breedte- en lengtecoördinaten van elke stad vinden door de lijst uit te breiden 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>
En dan de locatie waarvoor u moet uitbreiden 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>
Nogmaals, unnest_auto() vereenvoudigt de beschreven bewerking met enkele risico's die kunnen worden veroorzaakt door het wijzigen van de structuur van de binnenkomende gegevens:
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>
We kunnen ook gewoon naar het eerste adres van elke stad kijken:
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>
Of gebruik hoist() voor een duik met meerdere niveaus om direct naar toe te gaan 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]>
Discografie van Sharla Gelfand
Ten slotte zullen we kijken naar de meest complexe structuur: de discografie van Sharla Gelfand. Net als in de bovenstaande voorbeelden beginnen we met het converteren van de lijst naar een gegevensframe met één kolom en breiden we deze vervolgens uit zodat elke component een afzonderlijke kolom is. Ook transformeer ik de kolom date_added naar de juiste datum- en tijdnotatie in 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
Op dit niveau krijgen we informatie over wanneer elke schijf aan Sharla's discografie is toegevoegd, maar we zien geen gegevens over die schijven. Om dit te doen, moeten we de kolom uitbreiden basic_information:
discs %>% unnest_wider(basic_information)
#> Column name `id` must not be duplicated.
#> Use .name_repair to specify repair.
Helaas krijgen wij een foutmelding, omdat... binnen de lijst basic_information er is een kolom met dezelfde naam basic_information. Als een dergelijke fout optreedt, kunt u deze gebruiken om snel de oorzaak ervan te achterhalen names_repair = "unique":
U kunt ze vervolgens indien nodig weer samenvoegen met de oorspronkelijke gegevensset.
Conclusie
Tot de kern van de bibliotheek tidyverse bevat veel nuttige pakketten, verenigd door een gemeenschappelijke gegevensverwerkingsfilosofie.
In dit artikel hebben we de familie van functies onderzocht unnest_*(), die gericht zijn op het werken met het extraheren van elementen uit geneste lijsten. Dit pakket bevat nog veel meer handige functies die het gemakkelijker maken om gegevens volgens het concept te converteren Nette gegevens.