ProHoster > Blog > Adminisztráció > Beágyazott oszlopok kibontása – listák az R nyelv használatával (tidyr csomag és az unnest család funkciói)
Beágyazott oszlopok kibontása – listák az R nyelv használatával (tidyr csomag és az unnest család funkciói)
A legtöbb esetben, amikor egy API-tól kapott válasszal vagy bármilyen más, összetett fastruktúrájú adattal dolgozik, JSON- és XML-formátumokkal kell szembenéznie.
Ezeknek a formátumoknak számos előnye van: meglehetősen kompaktan tárolják az adatokat, és lehetővé teszik az információk szükségtelen megkettőzésének elkerülését.
E formátumok hátránya feldolgozásuk és elemzésük bonyolultsága. Strukturálatlan adatok nem használhatók a számításokhoz, és nem építhető rájuk a vizualizáció.
Ez a cikk logikus folytatása a kiadványnak "R csomag tidyr és új funkciói pivot_longer és pivot_wider". Segít abban, hogy a strukturálatlan adatstruktúrákat egy ismerős és elemzésre alkalmas táblázatos formába hozza a csomag segítségével tidyr, amely a könyvtár magjában található tidyverse, és annak funkciócsaládja unnest_*().
Tartalom
Ha érdekel az adatelemzés, akkor az én oldalam is érdekelheti távirat и youtube csatornák. A tartalom nagy része az R nyelvnek szól.
Téglalapozás(A fordító megjegyzése, nem találtam megfelelő fordítási lehetőséget ehhez a kifejezéshez, ezért hagyjuk úgy, ahogy van.) Az a folyamat, amelynek során a strukturálatlan adatokat beágyazott tömbökkel egy kétdimenziós táblázatba hozzuk, amely ismert sorokból és oszlopokból áll. BAN BEN tidyr Számos funkció segít a beágyazott listaoszlopok kibontásában és az adatok téglalap alakú, táblázatos formára való redukálásában:
unnest_longer() felveszi az oszloplista minden elemét, és létrehoz egy új sort.
unnest_wider() átveszi az oszloplista minden elemét, és létrehoz egy új oszlopot.
unnest_auto() automatikusan meghatározza, hogy melyik funkciót a legjobb használni unnest_longer() vagy unnest_wider().
hoist() hasonló unnest_wider() de csak a megadott összetevőket választja ki, és lehetővé teszi a több szintű beágyazást.
A strukturálatlan adatok többszintű egymásba ágyazásával kapcsolatos problémák többsége megoldható a felsorolt függvények dplyr-rel való kombinálásával.
Ezen technikák bemutatásához a csomagot fogjuk használni repurrrsive, amely több összetett, többszintű listát biztosít egy webes API-ból.
Kezdjük gh_users, egy lista, amely hat GitHub-felhasználóról tartalmaz információkat. Először is alakítsuk át a listát gh_users в tibble keret:
users <- tibble( user = gh_users )
Ez kissé ellentmondásosnak tűnik: miért kell listát adni gh_users, egy bonyolultabb adatszerkezetre? De egy adatkeretnek van egy nagy előnye: több vektort kombinál, így mindent egy objektumban követ.
Minden objektum elem users egy elnevezett lista, amelyben minden elem egy oszlopot jelöl.
Ebben az esetben van egy 30 oszlopból álló táblázatunk, és a legtöbbre nem lesz szükségünk, így helyette unnest_wider() használatához hoist(). hoist() lehetővé teszi számunkra, hogy a kiválasztott komponenseket ugyanazzal a szintaxissal bontsuk ki, mint 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() eltávolítja a megadott nevű összetevőket egy oszloplistából használóígy mérlegelheti hoist() mint a komponensek áthelyezése a dátumkeret belső listájáról a legfelső szintre.
Github adattárak
Lista igazítás gh_repos hasonlóan kezdjük a konvertálásával tibble:
Ezúttal az elemek használó a felhasználó tulajdonában lévő adattárak listáját képviselik. Minden adattár egy külön megfigyelés, tehát a tiszta adatok fogalma szerint (kb. rendezett adat) új sorokká kell válniuk, ezért használjuk unnest_longer() de nem 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
Most már használhatjuk unnest_wider() vagy 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
Ügyeljen a használatára c("owner", "login"): Ez lehetővé teszi, hogy egy beágyazott listából megkapjuk a második szintű értéket owner. Alternatív megoldás a teljes lista lekérése owner majd a funkció használatával unnest_wider() minden elemét helyezze egy oszlopba:
Ahelyett, hogy a megfelelő funkció kiválasztásán gondolkodna unnest_longer() vagy unnest_wider() Te tudod használni unnest_auto(). Ez a függvény többféle heurisztikus módszert alkalmaz az adatok átalakításához legmegfelelőbb függvény kiválasztásához, és üzenetet jelenít meg a választott módszerről.
got_chars azonos felépítésű gh_users: Ez elnevezett listák halmaza, ahol a belső lista minden eleme leírja a Game of Thrones karakterének valamilyen attribútumait. Hoz got_chars A táblázat nézetben az előző példákhoz hasonlóan először egy dátumkeretet hozunk létre, majd az egyes elemeket külön oszlopokká alakítjuk:
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>
Szerkezet got_chars valamivel nehezebb, mint gh_users, mert egyes összetevők listája char önmagukban egy lista, ennek eredményeként oszlopokat kapunk - listákat:
További lépései az elemzés céljaitól függenek. Talán információkat kell elhelyeznie minden egyes könyv és sorozat soraiban, amelyben a karakter megjelenik:
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
Vagy esetleg olyan táblázatot szeretne létrehozni, amely lehetővé teszi a karakter és a mű összeegyeztetését:
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
(Jegyezze meg az üres értékeket "" mezőben title, ennek oka az adatbevitel során elkövetett hibák got_chars: valójában olyan karakterek, amelyekhez nincs megfelelő könyv és tévésorozat címe a területen title 0 hosszúságú vektorral kell rendelkeznie, nem pedig az üres karakterláncot tartalmazó 1 hosszúságú vektorral.)
A fenti példát a függvény segítségével átírhatjuk unnest_auto(). Ez a megközelítés kényelmes egyszeri elemzéshez, de ne hagyatkozzon rá unnest_auto() rendszeres használatra. A lényeg az, hogy ha megváltozik az adatszerkezet unnest_auto() megváltoztathatja a kiválasztott adatátalakítási mechanizmust, ha kezdetben a lista oszlopait sorokká bontotta ki a használatával unnest_longer(), akkor amikor a bejövő adatok szerkezete megváltozik, a logika javára változtatható unnest_wider(), és ennek a megközelítésnek a folyamatos használata váratlan hibákhoz vezethet.
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
Geokódolás a Google segítségével
Ezután a Google geokódoló szolgáltatásából nyert adatok bonyolultabb szerkezetét tekintjük át. A hitelesítő adatok gyorsítótárazása ellentétes a Google Maps API-val való munkavégzés szabályaival, ezért először írok egy egyszerű wrappert az API köré. Amely a Google Maps API-kulcs környezeti változóban való tárolásán alapul; Ha nem rendelkezik a környezeti változókban tárolt kulccsal a Google Maps API-val való munkavégzéshez, akkor az ebben a részben bemutatott kódrészletek nem kerülnek végrehajtásra.
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)
}
A függvény által visszaadott lista meglehetősen összetett:
Szerencsére függvények segítségével lépésről lépésre meg tudjuk oldani azt a problémát, hogy ezeket az adatokat táblázatos formává alakítsuk tidyr. Hogy a feladat egy kicsit nagyobb kihívást és valószerűbb legyen, kezdek néhány város geokódolásával:
city <- c ( "Houston" , "LA" , "New York" , "Chicago" , "Springfield" ) city_geo <- purrr::map (city, geocode)
A kapott eredményt átszámítom tibble, a kényelem kedvéért hozzáadok egy oszlopot a megfelelő városnévvel.
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]>
Az első szint összetevőket tartalmaz status и result, amellyel bővíthetjük 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
Kérjük, vegye figyelembe, hogy a results egy többszintű lista. A legtöbb városnak 1 eleme van (ez a geokódolási API-nak megfelelő egyedi értéket képvisel), de Springfieldnek kettő. -val külön sorokba húzhatjuk őket 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
Most mindegyiknek ugyanazok az összetevői vannak, amelyek segítségével ellenőrizhető 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
Az egyes városok szélességi és hosszúsági koordinátáit a lista bővítésével találjuk meg 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>
És akkor a hely, amelyhez bővíteni kell 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>
Már megint, unnest_auto() leegyszerűsíti a leírt műveletet néhány kockázattal, amelyet a bejövő adatok szerkezetének megváltoztatása okozhat:
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>
Megnézhetjük az egyes városok első címét is:
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>
Vagy használja hoist() egy többszintű merüléshez közvetlenül 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 diszkográfiája
Végül megnézzük a legösszetettebb szerkezetet - Sharla Gelfand diszkográfiáját. A fenti példákhoz hasonlóan először a listát egyoszlopos adatkeretté alakítjuk, majd kibővítjük úgy, hogy minden összetevő külön oszlop legyen. Az oszlopot is átalakítom date_added a megfelelő dátum- és időformátumhoz R-ben.
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
Ezen a szinten információt kapunk arról, hogy az egyes lemezek mikor kerültek Sharla diszkográfiájába, de azokról a lemezekről nem látunk adatokat. Ehhez ki kell bővítenünk az oszlopot basic_information:
discs %>% unnest_wider(basic_information)
#> Column name `id` must not be duplicated.
#> Use .name_repair to specify repair.
Sajnos hibaüzenetet kapunk, mert... a listán belül basic_information van egy azonos nevű oszlop basic_information. Ha ilyen hiba történik, az okának gyors meghatározásához használhatja names_repair = "unique":
Ezután szükség szerint visszakapcsolhatja őket az eredeti adatkészlethez.
Következtetés
A könyvtár magjához tidyverse számos hasznos csomagot tartalmaz, amelyeket egy közös adatfeldolgozási filozófia egyesít.
Ebben a cikkben a függvénycsaládot vizsgáltuk unnest_*(), amelyek célja a beágyazott listák elemeinek kinyerése. Ez a csomag sok más hasznos funkciót is tartalmaz, amelyek megkönnyítik az adatok koncepció szerinti konvertálását Tiszta adatok.