在R中如何将NHL嵌套列表转换为球员统计DataFrame
NHL Boxscore数据处理解决方案
1. 修复单场数据合并问题
你之前用c()合并两个数据框的方式不对,会把它们拼成列表而非合并为一个DataFrame,另外stats里的核心统计数据藏在skaterStats子节点里,直接转data.frame会保留嵌套结构,导致后续无法正常合并。下面是修正后的单场数据处理代码:
library(nhlapi) library(dplyr) library(tidyr) # 获取单场比赛boxscore数据 boxscore <- nhl_games_boxscore(gameIds = 2023020001)[[1]] # 提取客队球员集合 away_players <- boxscore[["teams"]][["away"]][["players"]] # 提取球员基础信息(保留官网展示的关键字段) df_away_players <- lapply(away_players, function(player) { player[["person"]] %>% as.data.frame() %>% select(id, fullName, primaryNumber, position.code) }) %>% bind_rows() # 提取球员核心统计数据(从skaterStats节点提取) df_away_stats <- lapply(away_players, function(player) { player[["stats"]][["skaterStats"]] %>% as.data.frame() }) %>% bind_rows() # 正确合并球员信息与统计数据 df_combined <- bind_cols(df_away_players, df_away_stats) # 添加比赛日期(从比赛元数据中提取) game_date <- as.Date(boxscore[["gameData"]][["game"]][["dateTime"]]) df_combined <- df_combined %>% mutate(game_date = game_date)
2. 多场比赛批量处理
用purrr::map_dfr()可以批量处理多个比赛ID,自动把每场数据合并成一个大的DataFrame:
# 定义需要处理的比赛ID列表 game_ids <- c(2023020001, 2023020002, 2023020003) # 定义单场数据处理函数 process_single_game <- function(game_id) { boxscore <- nhl_games_boxscore(gameIds = game_id)[[1]] # 提取客队球员 away_players <- boxscore[["teams"]][["away"]][["players"]] # 球员基础信息 df_players <- lapply(away_players, function(p) { p[["person"]] %>% as.data.frame() %>% select(id, fullName, primaryNumber, position.code) }) %>% bind_rows() # 球员统计数据 df_stats <- lapply(away_players, function(p) { p[["stats"]][["skaterStats"]] %>% as.data.frame() }) %>% bind_rows() # 添加比赛标识信息 game_info <- data.frame( game_id = game_id, game_date = as.Date(boxscore[["gameData"]][["game"]][["dateTime"]]), away_team = boxscore[["teams"]][["away"]][["team"]][["name"]] ) # 合并所有数据 bind_cols(game_info, df_players, df_stats) } # 批量处理所有比赛并合并结果 all_games_data <- purrr::map_dfr(game_ids, process_single_game)
3. 对齐官网展示格式
如果要和NHL官网的boxscore格式完全匹配,可以做以下调整:
- 重命名列名,比如把
goals改成G、assists改成A,对应官网的缩写 - 筛选官网显示的核心字段:比如
plusMinus、shots、hits、timeOnIce等 - 门将的统计字段和滑冰球员不同,若需要包含门将,需单独提取
goalieStats节点的数据并分开处理
示例列名调整代码:
df_combined <- df_combined %>% rename( 球衣号 = primaryNumber, 姓名 = fullName, 位置 = position.code, 进球 = goals, 助攻 = assists, 得分 = points, 正负值 = plusMinus, 射门 = shots, 冲撞 = hits, 上场时间 = timeOnIce )
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

