如何将R语言中生成的嵌套列表转换为DataFrame?
解决多层嵌套列表中data.frame的合并问题
问题分析
你的final是三层嵌套列表(年份→月份→日期),每个日期节点下还包含2个对应两队的data.frame。之前的尝试仅处理了最外层,没有深入嵌套层级展开所有数据框,因此无法完成合并。
正确合并方法
方法1:用purrr逐层扁平化列表
先把所有嵌套的data.frame提取为一维列表,再合并:
library(purrr) library(dplyr) # 逐层展开嵌套列表,得到所有独立的data.frame all_dataframes <- final %>% flatten() %>% # 展开年份层 flatten() %>% # 展开月份层 flatten() # 展开日期层,提取所有单个data.frame # 合并为统一DataFrame final_df <- bind_rows(all_dataframes)
方法2:用rapply递归提取所有data.frame
rapply可递归遍历整个嵌套结构,自动收集所有data.frame类型的元素:
# 递归提取所有data.frame,返回一维列表 all_dataframes <- rapply(final, classes = "data.frame", how = "list", f = identity) # 合并所有数据框 final_df <- bind_rows(all_dataframes)
方法3:从根源简化存储(避免复杂嵌套)
可以在循环内直接将每个场次的两队数据追加到结果列表,无需构建多层嵌套:
# 初始化空列表存储单个data.frame final_list <- list() for (i in year) { for (j in month) { for (k in day) { skip_to_next <- FALSE url <- paste0('https://www.baseball-reference.com/boxes/ARI/ARI', i, j, k, '.shtml') Sys.sleep(5) game_path <- tryCatch(url |> read_html() |> html_nodes(xpath = '//div[contains(@id, "batting")]') |> map(\(x) x |> as.character() |> str_remove_all("<!--|-->") |> read_html() |> html_table()) |> unlist(recursive = FALSE), error = function(e) {skip_to_next <<- TRUE} ) if(skip_to_next) {next} url <- read_html(url) list_url <- url %>% html_nodes(xpath = "//td/a") %>% html_text() List_2_letters <- as.list(list_url[nchar(list_url) > 5]) game_path <- mapply(cbind, game_path, "Date" = paste(gsub('.{1}$', '', k), j, i, sep = '-'), SIMPLIFY=F) game_path <- Map(cbind, game_path, "Team" = List_2_letters) # 直接将当前场次的两个data.frame追加到结果列表 final_list <- c(final_list, game_path) } } } # 合并为统一DataFrame final_df <- bind_rows(final_list)
验证结果
执行合并后,可通过str(final_df)查看数据结构,确认所有场次的两队数据已整合到单个DataFrame中。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

