如何从多层嵌套列表提取信息并转换为DataFrame?
Got it, let's solve this nested list to DataFrame problem—this is such a common pain point with hierarchical data, especially when dealing with family trees or nested API outputs! The key here is to use a recursive function to traverse every level of the nested list, extract each person's attributes, and combine them all into a flat table.
Step 1: Build a Recursive Function with tidyverse
We'll create a function that handles both single family members and lists of members, recursively digging into any children sublists:
- Extracts all attributes except
childrenfor the current member - Recursively processes any nested
children - Combines the current member's data with their children's data into a single table
Here's the code:
library(tidyverse) flatten_family <- function(member_list) { # If input is a list of members, map the function over each one if (is.null(names(member_list))) { return(map_dfr(member_list, flatten_family)) } # Pull out the current member's attributes (exclude children) current_member <- member_list %>% keep(~!is.list(.x) || names(.x) != "children") %>% as_tibble_row() # Process children if they exist if (!is.null(member_list$children)) { children_data <- map_dfr(member_list$children, flatten_family) bind_rows(current_member, children_data) } else { # No children? Just return the current member's data current_member } }
Step 2: Apply the Function to Your family List
Run the function on your nested list, and you'll get a flat DataFrame where each row represents one family member. Missing attributes (like hair for most people) will automatically be filled with NA:
family_df <- flatten_family(family) # View the full result print(family_df, n = Inf)
What This Does
- Handles Any Nesting Depth: The function calls itself on every
childrensublist, so it works even if Harry grows up and has kids later! - Flexible Attributes:
as_tibble_rowandbind_rowshandle members with different attribute sets seamlessly—no errors if someone has ahairfield and others don't. - Clean, Flat Output: Every person in the family tree gets their own row with all their personal details.
Example Output Snippet
You'll see a table like this (truncated for brevity):
# A tibble: 11 × 4 name age eyes hair <chr> <dbl> <chr> <chr> 1 Alice 40 blue NA 2 Bob 20 blue NA 3 Charlie 18 brown NA 4 Dan 12 green NA 5 Erin 69 green NA 6 Frank 45 blue NA 7 George 24 blue NA 8 Harry 2 green NA 9 Ingrid 22 brown brown 10 Jack 29 brown NA 11 Larry 21 blue NA
Alternative for Shallow Nesting (Not Recommended for Arbitrary Depth)
If you knew the nesting level was fixed, you could use repeated unnest calls, but this gets messy fast with deeper trees:
tibble(family = family) %>% unnest_wider(family) %>% unnest_longer(children, keep_empty = TRUE) %>% unnest_wider(children, names_sep = "_")
Stick with the recursive function for true flexibility with any nesting depth.
内容的提问来源于stack exchange,提问作者CDoug

