ProHoster > Blog > Stjórnsýsla > Stækkandi hreiður dálkur - listar með R tungumálinu (tidyr pakki og aðgerðir unnest fjölskyldunnar)
Stækkandi hreiður dálkur - listar með R tungumálinu (tidyr pakki og aðgerðir unnest fjölskyldunnar)
Í flestum tilfellum, þegar þú vinnur með svar sem berast frá API, eða með önnur gögn sem hafa flókna trébyggingu, stendur þú frammi fyrir JSON og XML sniðum.
Þessi snið hafa marga kosti: þau geyma gögn nokkuð þétt og gera þér kleift að forðast óþarfa tvíföldun upplýsinga.
Ókosturinn við þessi snið er hversu flókin vinnsla þeirra og greining er. Ekki er hægt að nota óskipulögð gögn í útreikningum og ekki er hægt að byggja á þeim sjónmynd.
Þessi grein er rökrétt framhald af útgáfunni "R pakki tidyr og nýju aðgerðir hans pivot_longer og pivot_wider". Það mun hjálpa þér að koma óskipulögðu gagnaskipulagi í kunnuglegt og hentugur fyrir greiningartöfluform með því að nota pakkann tidyr, innifalinn í kjarna bókasafnsins tidyverse, og fjölskyldu hennar af aðgerðum unnest_*().
efni
Ef þú hefur áhuga á gagnagreiningu gætirðu haft áhuga á mínum símskeyti и YouTube rásir. Mest af efninu er tileinkað R tungumálinu.
Rétthyrningur(Athugasemd þýðanda, ég fann ekki fullnægjandi þýðingarmöguleika fyrir þetta hugtak, svo við látum það vera eins og það er.) er ferlið við að koma óskipulögðum gögnum með hreiðri fylki í tvívíða töflu sem samanstendur af kunnuglegum línum og dálkum. IN tidyr есть несколько функций, которые помогут вам развернуть вложенные столбцы-списки и привести данные к прямоугольной, табличной форме:
unnest_longer() tekur hvern þátt í dálkalistanum og býr til nýja línu.
unnest_wider() tekur hvern þátt í dálkalistanum og býr til nýjan dálk.
unnest_auto() ákvarðar sjálfkrafa hvaða aðgerð er best að nota unnest_longer() eða unnest_wider().
hoist() svipað unnest_wider() en velur aðeins tilgreinda hluti og gerir þér kleift að vinna með nokkrum stigum hreiður.
Flest vandamálin sem tengjast því að koma óskipulögðum gögnum með nokkrum stigum hreiður í tvívíða töflu er hægt að leysa með því að sameina upptaldar aðgerðir með dplyr.
Til að sýna fram á þessar aðferðir munum við nota pakkann repurrrsive, sem veitir marga flókna, fjölþrepa lista fengna úr API á vefnum.
Við skulum byrja gh_notendur, listi sem inniheldur upplýsingar um sex GitHub notendur. Fyrst skulum við umbreyta listann gh_notendur в tibbla rammi:
users <- tibble( user = gh_users )
Þetta virðist svolítið gagnsætt: hvers vegna að gefa upp lista gh_notendur, til flóknari gagnaskipulags? En gagnarammi hefur stóran kost: hann sameinar marga vektora þannig að allt er rakið í einum hlut.
Hver hlutur þáttur users er nafngreindur listi þar sem hver þáttur táknar dálk.
Í þessu tilfelli höfum við töflu sem samanstendur af 30 dálkum og við munum ekki þurfa flesta þeirra, svo við getum í staðinn unnest_wider() nota hoist(). hoist() gerir okkur kleift að draga út valda íhluti með því að nota sömu setningafræði og 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() fjarlægir tilgreinda nafngreinda hluti af dálkalista notandisvo þú getur íhugað hoist() eins og að færa íhluti af innri lista dagsetningarramma yfir á efsta stig hans.
Github geymslur
Listajöfnun gh_repos við byrjum svipað á því að breyta því í tibble:
Að þessu sinni þættirnir notandi tákna lista yfir geymslur í eigu þessa notanda. Hver geymsla er sérstök athugun, svo samkvæmt hugmyndinni um snyrtileg gögn (u.þ.b. snyrtileg gögn) þær ættu að verða nýjar línur, þess vegna notum við unnest_longer() og ekki 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
Nú getum við notað unnest_wider() eða 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
Gefðu gaum að notkuninni c("owner", "login"): Þetta gerir okkur kleift að fá annað stigs gildi úr hreiðri lista owner. Önnur aðferð er að fá allan listann owner og nota síðan aðgerðina unnest_wider() settu hvert frumefni í dálk:
Í stað þess að hugsa um að velja rétta aðgerðina unnest_longer() eða unnest_wider() þú getur notað unnest_auto(). Þessi aðgerð notar nokkrar heuristic aðferðir til að velja heppilegustu aðgerðina til að umbreyta gögnunum og birtir skilaboð um valda aðferð.
got_chars hefur sams konar uppbyggingu og gh_users: Þetta er sett af nafngreindum listum, þar sem hver þáttur innri lista lýsir einhverjum eiginleikum Game of Thrones persónu. Koma með got_chars Fyrir töfluyfirlitið byrjum við á því að búa til dagsetningarramma, alveg eins og í fyrri dæmum, og umbreytum síðan hverri einingu í sérstakan dálk:
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>
Uppbygging got_chars nokkuð erfiðara en gh_users, vegna þess sumir lista hluti char sjálfir eru listi, þar af leiðandi fáum við stoðir - lista:
Frekari aðgerðir þínar ráðast af markmiðum greiningarinnar. Kannski þarftu að setja upplýsingar á línurnar fyrir hverja bók og seríu sem persónan birtist í:
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
Eða kannski viltu búa til töflu sem gerir þér kleift að passa persónuna og verkið:
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
(Athugaðu tómu gildin "" á sviði title, þetta er vegna villna sem gerðar voru þegar gögn voru færð inn í got_chars: reyndar persónur sem engar samsvarandi bóka- og sjónvarpsseríutitlar eru til á þessu sviði title verður að hafa vigur af lengd 0, ekki vektor af lengd 1 sem inniheldur tóma strenginn.)
Við getum endurskrifað dæmið hér að ofan með því að nota aðgerðina unnest_auto(). Þessi aðferð er hentug fyrir einskiptisgreiningu, en þú ættir ekki að treysta á unnest_auto() til notkunar reglulega. Málið er að ef gagnauppbyggingin þín breytist unnest_auto() getur breytt völdum gagnaumbreytingarkerfi ef það stækkaði listadálka upphaflega í línur með unnest_longer(), þá þegar uppbygging komandi gagna breytist er hægt að breyta rökfræðinni í hag unnest_wider(), og að nota þessa nálgun viðvarandi getur leitt til óvæntra villna.
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
Landkóðun með Google
Næst munum við skoða flóknari uppbyggingu gagna sem fást úr landkóðunþjónustu Google. Skilríki í skyndiminni stangast á við reglur um að vinna með Google maps API, svo ég mun fyrst skrifa einfalda umbúðir utan um API. Sem byggir á því að geyma Google Maps API lykilinn í umhverfisbreytu; Ef þú ert ekki með lykilinn til að vinna með Google Maps API geymdan í umhverfisbreytunum þínum, verða kóðabrotin sem sýnd eru í þessum hluta ekki keyrð.
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)
}
Listinn sem þessi aðgerð skilar er nokkuð flókinn:
Sem betur fer getum við leyst vandamálið við að breyta þessum gögnum í töfluform skref fyrir skref með því að nota aðgerðir tidyr. Til að gera verkefnið aðeins meira krefjandi og raunhæfara, byrja ég á því að landkóða nokkrar borgir:
city <- c ( "Houston" , "LA" , "New York" , "Chicago" , "Springfield" ) city_geo <- purrr::map (city, geocode)
Ég mun umbreyta niðurstöðunni í tibble, til hægðarauka mun ég bæta við dálki með samsvarandi borgarnafni.
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]>
Fyrsta stigið inniheldur hluti status и result, sem við getum stækkað með 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
takið eftir því results er fjölþrepa listi. Flestar borgir hafa 1 frumefni (sem táknar einstakt gildi sem samsvarar landkóðun API), en Springfield hefur tvö. Við getum dregið þá í aðskildar línur með 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
Nú hafa þeir allir sömu íhluti, sem hægt er að sannreyna með því að nota 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
Við getum fundið breiddar- og lengdargráðuhnit hverrar borgar með því að stækka listann 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>
Og svo staðsetningin sem þú þarft að stækka fyrir 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>
Enn og aftur unnest_auto() einfaldar aðgerðina sem lýst er með nokkrum áhættum sem geta stafað af því að breyta uppbyggingu komandi gagna:
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>
Við getum líka bara skoðað fyrsta heimilisfangið fyrir hverja borg:
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>
Eða nota hoist() fyrir fjölþrepa köfun til að fara beint í 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]>
Skífafræði Sharla Gelfand
Að lokum munum við skoða flóknustu uppbygginguna - diskógrafíu Sharla Gelfand. Eins og í dæmunum hér að ofan byrjum við á því að breyta listanum í einn dálk gagnaramma og lengjum hann svo þannig að hver hluti sé sérstakur dálkur. Einnig umbreyti ég dálknum date_added í viðeigandi dagsetningar- og tímasniði í 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
Á þessu stigi fáum við upplýsingar um hvenær hver diskur var bætt við diskafræði Sharla, en við sjáum engin gögn um þá diska. Til að gera þetta þurfum við að stækka dálkinn basic_information:
discs %>% unnest_wider(basic_information)
#> Column name `id` must not be duplicated.
#> Use .name_repair to specify repair.
Því miður munum við fá villu, vegna þess að... inni á listanum basic_information þar er dálkur með sama nafni basic_information. Ef slík villa kemur upp, til að fljótt ákvarða orsök hennar, geturðu notað names_repair = "unique":
Þú getur síðan tengt þá aftur við upprunalega gagnasafnið eftir þörfum.
Ályktun
Til kjarna bókasafnsins tidyverse inniheldur marga gagnlega pakka sem sameinast um sameiginlega gagnavinnslu hugmyndafræði.
Í þessari grein skoðuðum við fjölskyldu aðgerða unnest_*(), sem miða að því að vinna með að draga þætti úr hreiðri listum. Þessi pakki inniheldur marga aðra gagnlega eiginleika sem gera það auðveldara að umbreyta gögnum í samræmi við hugmyndina Snyrtileg gögn.