ProHoster > وبلاگ > اداره > گسترش ستونهای تودرتو - لیستهایی با استفاده از زبان R (بسته tidyr و توابع خانواده unnest)
گسترش ستونهای تودرتو - لیستهایی با استفاده از زبان R (بسته tidyr و توابع خانواده unnest)
در بیشتر موارد، هنگام کار با یک پاسخ دریافت شده از یک API، یا با هر داده دیگری که ساختار درختی پیچیده ای دارد، با فرمت های JSON و XML مواجه می شوید.
این فرمت ها مزایای زیادی دارند: آنها داده ها را کاملا فشرده ذخیره می کنند و به شما امکان می دهند از تکرار غیر ضروری اطلاعات جلوگیری کنید.
نقطه ضعف این فرمت ها پیچیدگی پردازش و تحلیل آنهاست. داده های بدون ساختار را نمی توان در محاسبات استفاده کرد و نمی توان روی آن تجسم ساخت.
این مقاله ادامه منطقی انتشار است "بسته R tidyr و توابع جدید آن pivot_longer و pivot_wider". این به شما کمک می کند تا ساختارهای داده بدون ساختار را با استفاده از بسته به شکل جدولی آشنا و مناسب برای تجزیه و تحلیل بیاورید tidyr، در هسته کتابخانه گنجانده شده است tidyverseو خانواده توابع آن unnest_*().
مقدار
اگر به تجزیه و تحلیل داده ها علاقه دارید، ممکن است به من علاقه مند شوید تلگراف и یوتیوب کانال ها بیشتر مطالب به زبان R اختصاص داده شده است.
مستطیل(یادداشت مترجم، من گزینههای ترجمه مناسبی برای این اصطلاح پیدا نکردم، بنابراین آن را همانطور که هست رها میکنیم.) فرآیند آوردن داده های بدون ساختار با آرایه های تو در تو در یک جدول دو بعدی متشکل از سطرها و ستون های آشنا است. که در tidyr چندین عملکرد وجود دارد که به شما کمک می کند ستون های لیست تودرتو را گسترش دهید و داده ها را به شکل مستطیلی و جدولی کاهش دهید:
unnest_longer() هر عنصر از لیست ستون را می گیرد و یک ردیف جدید ایجاد می کند.
unnest_wider() هر عنصر از لیست ستون را می گیرد و یک ستون جدید ایجاد می کند.
unnest_auto() به طور خودکار تعیین می کند که کدام عملکرد بهتر است استفاده شود unnest_longer() یا unnest_wider().
hoist() شبیه به unnest_wider() اما فقط اجزای مشخص شده را انتخاب می کند و به شما امکان می دهد با چندین سطح از تودرتو کار کنید.
بسیاری از مشکلات مربوط به آوردن داده های بدون ساختار با چندین سطح تودرتو در یک جدول دو بعدی را می توان با ترکیب توابع فهرست شده با dplyr حل کرد.
برای نشان دادن این تکنیک ها، از بسته استفاده می کنیم repurrrsive، که چندین لیست پیچیده و چند سطحی مشتق شده از یک وب API را ارائه می دهد.
بیایید شروع کنیم gh_users، لیستی که حاوی اطلاعاتی در مورد شش کاربر GitHub است. ابتدا بیایید لیست را تغییر دهیم gh_users в تیبل قاب:
users <- tibble( user = gh_users )
این کمی غیر منطقی به نظر می رسد: چرا یک لیست ارائه کنید gh_users، به یک ساختار داده پیچیده تر؟ اما یک قاب داده یک مزیت بزرگ دارد: چندین بردار را ترکیب می کند تا همه چیز در یک شی ردیابی شود.
هر عنصر شی users یک لیست با نام است که در آن هر عنصر نشان دهنده یک ستون است.
در این مورد، ما یک جدول متشکل از 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:
این بار عناصر کاربر فهرستی از مخازن متعلق به این کاربر را نشان می دهد. هر مخزن یک مشاهده جداگانه است، بنابراین با توجه به مفهوم داده های منظم (تقریباً داده های مرتب) آنها باید به خطوط جدیدی تبدیل شوند، به همین دلیل است که ما استفاده می کنیم 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() هر یک از عناصر آن را در یک ستون قرار دهید:
به جای اینکه به انتخاب عملکرد مناسب فکر کنید unnest_longer() یا unnest_wider() شما می توانید استفاده کنید unnest_auto(). این تابع از چندین روش اکتشافی برای انتخاب مناسب ترین تابع برای تبدیل داده ها استفاده می کند و پیامی در مورد روش انتخابی نمایش می دهد.
got_chars ساختاری مشابه دارد gh_users: این مجموعهای از فهرستهای نامگذاری شده است، که در آن هر عنصر از فهرست داخلی، برخی از ویژگیهای شخصیت بازی تاج و تخت را توصیف میکند. به ارمغان آوردن 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(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 را بررسی خواهیم کرد. ذخیره اعتبارنامه ها برخلاف قوانین کار با API نقشه های گوگل است، بنابراین ابتدا یک بسته بندی ساده در اطراف API می نویسم. که مبتنی بر ذخیره کلید Google Maps API در یک متغیر محیطی است. اگر کلید کار با Google Maps API را در متغیرهای محیط خود ذخیره نکنید، قطعات کد ارائه شده در این بخش اجرا نخواهند شد.
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)
}
خوشبختانه می توانیم با استفاده از توابع مشکل تبدیل این داده ها به شکل جدولی را مرحله به مرحله حل کنیم. 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 جغرافیایی)، اما اسپرینگفیلد دارای دو عنصر است. ما می توانیم آنها را به خطوط جداگانه بکشیم 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]>
دیسکوگرافی شارلا گلفاند
در نهایت، ما به پیچیده ترین ساختار - دیسکوگرافی شارلا گلفاند نگاه خواهیم کرد. مانند مثال های بالا، با تبدیل لیست به یک قاب داده تک ستونی شروع می کنیم و سپس آن را طوری گسترش می دهیم که هر جزء یک ستون جداگانه باشد. همچنین ستون را تبدیل می کنم 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
در این سطح، ما اطلاعاتی در مورد زمان اضافه شدن هر دیسک به دیسکوگرافی شارلا به دست می آوریم، اما هیچ داده ای در مورد آن دیسک ها نمی بینیم. برای این کار باید ستون را گسترش دهیم 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":
سپس می توانید در صورت نیاز آنها را به مجموعه داده اصلی ملحق کنید.
نتیجه
تا هسته اصلی کتابخانه tidyverse شامل بسیاری از بسته های مفید است که توسط یک فلسفه پردازش داده مشترک متحد شده اند.
در این مقاله به بررسی خانواده توابع پرداختیم unnest_*()، که با هدف کار با استخراج عناصر از لیست های تودرتو هستند. این بسته شامل بسیاری از ویژگی های مفید دیگر است که تبدیل داده ها مطابق با مفهوم را آسان می کند داده های مرتب.