Prohoster > Blog > quản lý > Mở rộng các cột lồng nhau - danh sách sử dụng ngôn ngữ R (gói tidyr và các chức năng của họ không lồng nhau)
Mở rộng các cột lồng nhau - danh sách sử dụng ngôn ngữ R (gói tidyr và các chức năng của họ không lồng nhau)
Trong hầu hết các trường hợp, khi làm việc với phản hồi nhận được từ API hoặc với bất kỳ dữ liệu nào khác có cấu trúc cây phức tạp, bạn sẽ phải đối mặt với các định dạng JSON và XML.
Các định dạng này có nhiều ưu điểm: chúng lưu trữ dữ liệu khá nhỏ gọn và cho phép bạn tránh sự trùng lặp thông tin không cần thiết.
Nhược điểm của các định dạng này là sự phức tạp trong quá trình xử lý và phân tích. Dữ liệu phi cấu trúc không thể được sử dụng trong tính toán và trực quan hóa không thể được xây dựng trên đó.
Bài viết này là sự tiếp nối hợp lý của ấn phẩm "Gói R gọn gàng và các hàm mới của nó là Pivot_longer và Pivot_wider". Nó sẽ giúp bạn đưa các cấu trúc dữ liệu phi cấu trúc thành dạng bảng quen thuộc và phù hợp để phân tích bằng cách sử dụng gói tidyr, được bao gồm trong lõi của thư viện tidyverse, và họ hàm của nó unnest_*().
nội dung
Nếu bạn quan tâm đến phân tích dữ liệu, bạn có thể quan tâm đến tôi điện tín и youtube kênh truyền hình. Hầu hết nội dung được dành cho ngôn ngữ R.
Hình chữ nhật(lưu ý của người dịch, tôi không tìm thấy các tùy chọn dịch thích hợp cho thuật ngữ này, vì vậy chúng tôi sẽ giữ nguyên như vậy.) là quá trình đưa dữ liệu phi cấu trúc với các mảng lồng nhau vào bảng hai chiều gồm các hàng và cột quen thuộc. TRONG tidyr Có một số hàm sẽ giúp bạn mở rộng các cột danh sách lồng nhau và giảm dữ liệu thành dạng bảng, hình chữ nhật:
unnest_longer() lấy từng phần tử của danh sách cột và tạo một hàng mới.
unnest_wider() lấy từng phần tử của danh sách cột và tạo một cột mới.
unnest_auto() tự động xác định chức năng nào là tốt nhất để sử dụng unnest_longer() hoặc unnest_wider().
hoist() tương tự như unnest_wider() nhưng chỉ chọn các thành phần được chỉ định và cho phép bạn làm việc với nhiều cấp độ lồng nhau.
Hầu hết các vấn đề liên quan đến việc đưa dữ liệu phi cấu trúc với nhiều cấp độ lồng nhau vào bảng hai chiều có thể được giải quyết bằng cách kết hợp các hàm được liệt kê với dplyr.
Để chứng minh những kỹ thuật này, chúng tôi sẽ sử dụng gói repurrrsive, cung cấp nhiều danh sách phức tạp, đa cấp bắt nguồn từ API web.
Hãy bắt đầu với gh_users, một danh sách chứa thông tin về sáu người dùng GitHub. Đầu tiên hãy chuyển đổi danh sách gh_users в làm vụn khung:
users <- tibble( user = gh_users )
Điều này có vẻ hơi phản trực giác: tại sao lại cung cấp danh sách gh_users, sang cấu trúc dữ liệu phức tạp hơn? Nhưng khung dữ liệu có một lợi thế lớn: nó kết hợp nhiều vectơ để mọi thứ được theo dõi trong một đối tượng.
Mỗi phần tử đối tượng users là một danh sách được đặt tên trong đó mỗi phần tử đại diện cho một cột.
Trong trường hợp này, chúng ta có một bảng gồm 30 cột và chúng ta sẽ không cần hầu hết các cột đó, vì vậy thay vào đó chúng ta có thể unnest_wider() sử dụng hoist(). hoist() cho phép chúng tôi trích xuất các thành phần đã chọn bằng cú pháp tương tự như 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() xóa các thành phần được đặt tên đã chỉ định khỏi danh sách cột người sử dụngvì vậy bạn có thể xem xét hoist() như di chuyển các thành phần từ danh sách nội bộ của khung ngày lên cấp cao nhất.
Kho lưu trữ Github
Căn chỉnh danh sách gh_repos chúng tôi bắt đầu tương tự bằng cách chuyển đổi nó thành tibble:
Lần này các yếu tố người sử dụng đại diện cho danh sách các kho lưu trữ thuộc sở hữu của người dùng này. Mỗi kho lưu trữ là một quan sát riêng biệt, do đó, theo khái niệm dữ liệu gọn gàng (dữ liệu gần đúng) chúng sẽ trở thành dòng mới, đó là lý do tại sao chúng tôi sử dụng unnest_longer() nhưng không 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
Bây giờ chúng ta có thể sử dụng unnest_wider() hoặc 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
Chú ý đến việc sử dụng c("owner", "login"): Điều này cho phép chúng tôi nhận giá trị cấp thứ hai từ danh sách lồng nhau owner. Một cách tiếp cận khác là lấy toàn bộ danh sách owner và sau đó sử dụng chức năng unnest_wider() đặt từng phần tử của nó vào một cột:
Thay vì suy nghĩ về việc lựa chọn chức năng phù hợp unnest_longer() hoặc unnest_wider() bạn có thể dùng unnest_auto(). Hàm này sử dụng một số phương pháp phỏng đoán để chọn hàm phù hợp nhất cho việc chuyển đổi dữ liệu và hiển thị thông báo về phương pháp đã chọn.
got_chars có cấu trúc giống hệt với gh_users: Đây là một tập hợp các danh sách được đặt tên, trong đó mỗi thành phần của danh sách bên trong mô tả một số thuộc tính của nhân vật Game of Thrones. Đưa got_chars Đối với chế độ xem bảng, chúng tôi bắt đầu bằng cách tạo khung ngày, giống như trong các ví dụ trước, sau đó chuyển đổi từng phần tử thành một cột riêng biệt:
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>
Cấu trúc got_chars có phần khó khăn hơn gh_users, bởi vì một số thành phần danh sách char bản thân chúng là một danh sách, kết quả là chúng ta có được các trụ cột - danh sách:
Các hành động tiếp theo của bạn phụ thuộc vào mục tiêu phân tích. Có lẽ bạn cần đưa thông tin vào dòng cho từng cuốn sách và bộ truyện mà nhân vật xuất hiện:
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
Hoặc có thể bạn muốn tạo một bảng cho phép bạn so khớp nhân vật và tác phẩm:
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
(Lưu ý các giá trị trống "" trong lĩnh vực title, nguyên nhân là do có lỗi khi nhập dữ liệu vào got_chars: trên thực tế, các nhân vật không có tên sách và phim truyền hình tương ứng trong lĩnh vực này title phải có vectơ có độ dài 0, không phải vectơ có độ dài 1 chứa chuỗi trống.)
Chúng ta có thể viết lại ví dụ trên bằng hàm unnest_auto(). Cách tiếp cận này thuận tiện cho việc phân tích một lần, nhưng bạn không nên dựa vào unnest_auto() để sử dụng một cách thường xuyên. Vấn đề là nếu cấu trúc dữ liệu của bạn thay đổi unnest_auto() có thể thay đổi cơ chế chuyển đổi dữ liệu đã chọn nếu ban đầu nó mở rộng các cột danh sách thành các hàng bằng cách sử dụng unnest_longer(), thì khi cấu trúc của dữ liệu đến thay đổi, logic có thể được thay đổi theo hướng có lợi unnest_wider()và việc sử dụng phương pháp này liên tục có thể dẫn đến những lỗi không mong muốn.
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
Mã hóa địa lý với Google
Tiếp theo, chúng ta sẽ xem xét cấu trúc dữ liệu phức tạp hơn thu được từ dịch vụ mã hóa địa lý của Google. Thông tin đăng nhập vào bộ nhớ đệm là trái với các quy tắc làm việc với API Google maps, vì vậy trước tiên tôi sẽ viết một trình bao bọc đơn giản xung quanh API. Điều này dựa trên việc lưu trữ khóa API Google Maps trong một biến môi trường; Nếu bạn không có khóa để làm việc với API Google Maps được lưu trữ trong các biến môi trường của mình thì các đoạn mã được trình bày trong phần này sẽ không được thực thi.
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)
}
May mắn thay, chúng ta có thể giải quyết vấn đề chuyển đổi dữ liệu này thành dạng bảng từng bước bằng cách sử dụng các hàm tidyr. Để làm cho nhiệm vụ trở nên khó khăn và thực tế hơn một chút, tôi sẽ bắt đầu bằng cách mã hóa địa lý một vài thành phố:
city <- c ( "Houston" , "LA" , "New York" , "Chicago" , "Springfield" ) city_geo <- purrr::map (city, geocode)
Tôi sẽ chuyển đổi kết quả kết quả thành tibble, để thuận tiện, tôi sẽ thêm một cột có tên thành phố tương ứng.
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]>
Cấp độ đầu tiên chứa các thành phần status и result, mà chúng ta có thể mở rộng với 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
Xin lưu ý rằng results là một danh sách đa cấp. Hầu hết các thành phố đều có 1 phần tử (đại diện cho một giá trị duy nhất tương ứng với API mã hóa địa lý), nhưng Springfield có hai phần tử. Chúng ta có thể kéo chúng thành các dòng riêng biệt với 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
Bây giờ tất cả chúng đều có các thành phần giống nhau, có thể được xác minh bằng cách sử dụng 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
Chúng ta có thể tìm thấy tọa độ kinh độ và vĩ độ của từng thành phố bằng cách mở rộng danh sách 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>
Và sau đó là vị trí bạn cần mở rộng 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>
Lần nữa, unnest_auto() đơn giản hóa hoạt động được mô tả với một số rủi ro có thể xảy ra do thay đổi cấu trúc của dữ liệu đến:
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>
Chúng ta cũng có thể chỉ cần nhìn vào địa chỉ đầu tiên của mỗi thành phố:
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>
Hoặc dùng hoist() để lặn nhiều cấp độ để đi thẳng đến 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]>
Discography of Sharla Gelfand
Cuối cùng, chúng ta sẽ xem xét cấu trúc phức tạp nhất - đĩa hát của Sharla Gelfand. Như trong các ví dụ ở trên, chúng tôi bắt đầu bằng cách chuyển đổi danh sách thành khung dữ liệu một cột, sau đó mở rộng danh sách để mỗi thành phần là một cột riêng biệt. Ngoài ra tôi chuyển đổi cột date_added sang định dạng ngày và giờ thích hợp trong 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
Ở cấp độ này, chúng tôi nhận được thông tin về thời điểm mỗi đĩa được thêm vào danh sách đĩa hát của Sharla nhưng chúng tôi không thấy bất kỳ dữ liệu nào về các đĩa đó. Để làm điều này chúng ta cần mở rộng cột basic_information:
discs %>% unnest_wider(basic_information)
#> Column name `id` must not be duplicated.
#> Use .name_repair to specify repair.
Thật không may, chúng tôi sẽ gặp lỗi vì... bên trong danh sách basic_information có một cột có cùng tên basic_information. Nếu xảy ra lỗi như vậy, để nhanh chóng xác định nguyên nhân, bạn có thể sử dụng names_repair = "unique":
Sau đó, bạn có thể nối chúng trở lại tập dữ liệu ban đầu nếu cần.
Kết luận
Đến cốt lõi của thư viện tidyverse bao gồm nhiều gói hữu ích được thống nhất bởi triết lý xử lý dữ liệu chung.
Trong bài viết này chúng ta đã xem xét nhóm hàm unnest_*(), nhằm mục đích làm việc với việc trích xuất các phần tử từ danh sách lồng nhau. Gói này chứa nhiều tính năng hữu ích khác giúp chuyển đổi dữ liệu theo khái niệm dễ dàng hơn Dữ liệu gọn gàng.