ProHoster > بلوق > إدارة > قم بتوسيع الأعمدة المتداخلة - القوائم التي تستخدم لغة R (حزمة tidyr و unnest family وظائف)
قم بتوسيع الأعمدة المتداخلة - القوائم التي تستخدم لغة R (حزمة tidyr و unnest family وظائف)
في معظم الحالات، عند العمل مع استجابة مستلمة من واجهة برمجة التطبيقات (API)، أو مع أي بيانات أخرى تحتوي على بنية شجرة معقدة، تواجه تنسيقات JSON وXML.
تتمتع هذه التنسيقات بالعديد من المزايا: فهي تخزن البيانات بشكل مضغوط تمامًا وتسمح لك بتجنب الازدواجية غير الضرورية للمعلومات.
عيب هذه التنسيقات هو تعقيد معالجتها وتحليلها. لا يمكن استخدام البيانات غير المنظمة في العمليات الحسابية ولا يمكن البناء عليها في التصور.
هذه المقالة هي استمرار منطقي للنشر ""حزمة R tidir ووظائفها الجديدة Pivot_longer وPivot_Wider". سيساعدك ذلك على تحويل هياكل البيانات غير المنظمة إلى نموذج جدولي مألوف ومناسب للتحليل باستخدام الحزمة tidyr، المدرجة في قلب المكتبة tidyverse، وعائلة وظائفها unnest_*().
محتوى
إذا كنت مهتمًا بتحليل البيانات ، فقد تكون مهتمًا ببرنامجي تيليجرام и موقع YouTube القنوات. معظم محتوياته مخصص للغة R.
مستطيل(ملاحظة المترجم، لم أجد خيارات ترجمة مناسبة لهذا المصطلح، لذلك سنتركه كما هو.) هي عملية جلب البيانات غير المنظمة بمصفوفات متداخلة إلى جدول ثنائي الأبعاد يتكون من صفوف وأعمدة مألوفة. في tidyr هناك العديد من الوظائف التي ستساعدك على توسيع أعمدة القائمة المتداخلة وتقليل البيانات إلى نموذج جدولي مستطيل:
unnest_longer() يأخذ كل عنصر من قائمة الأعمدة وينشئ صفًا جديدًا.
unnest_wider() يأخذ كل عنصر من قائمة الأعمدة وينشئ عمودًا جديدًا.
unnest_auto() يحدد تلقائيًا الوظيفة الأفضل للاستخدام unnest_longer() أو unnest_wider().
hoist() مشابه ل unnest_wider() ولكنه يحدد فقط المكونات المحددة ويسمح لك بالعمل مع عدة مستويات من التداخل.
يمكن حل معظم المشكلات المرتبطة بإحضار بيانات غير منظمة ذات مستويات متعددة من التداخل في جدول ثنائي الأبعاد من خلال الجمع بين الوظائف المدرجة مع dplyr.
لتوضيح هذه التقنيات، سوف نستخدم الحزمة repurrrsive، والذي يوفر عدة قوائم معقدة ومتعددة المستويات مستمدة من واجهة برمجة تطبيقات الويب.
لنبدأ 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() مثل نقل المكونات من القائمة الداخلية لإطار التاريخ إلى مستواه الأعلى.
مستودعات جيثب
محاذاة القائمة 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. يعد التخزين المؤقت لبيانات الاعتماد مخالفًا لقواعد العمل مع واجهة برمجة التطبيقات لخرائط Google، لذا سأكتب أولاً غلافًا بسيطًا حول واجهة برمجة التطبيقات. والذي يعتمد على تخزين مفتاح Google Maps 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)
}
ولحسن الحظ، يمكننا حل مشكلة تحويل هذه البيانات إلى نموذج جدولي خطوة بخطوة باستخدام الوظائف 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 هي قائمة متعددة المستويات. تحتوي معظم المدن على عنصر واحد (يمثل قيمة فريدة تتوافق مع واجهة برمجة تطبيقات الترميز الجغرافي)، ولكن لدى 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]>
ديسكغرافيا شارلا جلفاند
أخيرًا، سننظر إلى الهيكل الأكثر تعقيدًا - ديسكغرافيا شارلا جلفاند. كما في الأمثلة أعلاه، نبدأ بتحويل القائمة إلى إطار بيانات ذي عمود واحد، ثم نقوم بتوسيعها بحيث يكون كل مكون عمودًا منفصلاً. كما أقوم بتحويل العمود 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_*()والتي تهدف إلى العمل على استخراج العناصر من القوائم المتداخلة. تحتوي هذه الحزمة على العديد من الميزات المفيدة الأخرى التي تسهل تحويل البيانات وفقًا للمفهوم بيانات مرتبة.