Python转R新手:如何将含单元素与子列表的嵌套列表转为data.frame?
嵌套列表转data.frame的几种方法
针对你这种包含单个元素和子列表的嵌套结构,这里有几种实用的R方法,不管是单个列表转一行,还是多个列表转多行都适用:
方法1:用jsonlite包(最简洁,类似Python的json_normalize)
这个方法和Python里处理嵌套JSON的思路一致,先把列表转成JSON格式,再解析成扁平化的data.frame:
# 安装包(首次使用需要安装) # install.packages("jsonlite") library(jsonlite) # 单个嵌套列表转成一行data.frame complexList <- list(distance=1, activity=list(key=2, id="a"), other=12, stuff=list(a=3, b=4)) single_df <- fromJSON(toJSON(complexList), flatten = TRUE) # 多个嵌套列表转成多行data.frame list1 <- list(distance=1, activity=list(key=2, id="a"), other=12, stuff=list(a=3, b=4)) list2 <- list(distance=5, activity=list(key=6, id="b"), other=15, stuff=list(a=7, b=8)) multiple_lists <- list(list1, list2) multiple_df <- fromJSON(toJSON(multiple_lists), flatten = TRUE)
运行后single_df就是你要的单行结果,multiple_df会自动把每个列表作为一行。
方法2:用tidyverse工具链(R数据分析常用生态)
如果你以后要做更多数据处理,tidyverse是必学的,这里用tibble和unnest_wider来展开嵌套结构:
# 安装包(首次使用需要安装) # install.packages("tidyverse") library(tidyverse) # 单个列表转单行df single_df <- tibble(data = list(complexList)) %>% unnest_wider(data) %>% # 展开第一层列表 unnest_wider(activity, names_sep = ".") %>% # 展开activity子列表,用.分隔列名 unnest_wider(stuff, names_sep = ".") # 展开stuff子列表 # 多个列表转多行df multiple_df <- map_dfr(multiple_lists, function(x) { # 对每个列表,先把子列表转成tibble,再合并成一行 x %>% map_if(is.list, as_tibble) %>% bind_cols() })
方法3:基础R实现(无需额外安装包)
如果不想加载任何包,可以写一个递归函数手动展开嵌套列表:
# 定义递归展开函数:把嵌套子列表的键名用父键名+.连接 flatten_list <- function(input_list) { flat_result <- list() for (i in seq_along(input_list)) { current_name <- names(input_list)[i] current_value <- input_list[[i]] if (is.list(current_value)) { # 递归展开子列表 sub_flat <- flatten_list(current_value) # 给子列表的键名加上父键名前缀 names(sub_flat) <- paste(current_name, names(sub_flat), sep = ".") flat_result <- c(flat_result, sub_flat) } else { flat_result[[current_name]] <- current_value } } return(flat_result) } # 单个列表处理 flat_single <- flatten_list(complexList) single_df <- as.data.frame(t(flat_single)) # t()转置是因为单个扁平化列表是向量,转成单行df # 多个列表处理 flat_multiple <- lapply(multiple_lists, flatten_list) multiple_df <- do.call(rbind, lapply(flat_multiple, as.data.frame))
内容的提问来源于stack exchange,提问作者FredMaster
相关产品推荐
相关产品推荐

