You need to enable JavaScript to run this app. 使用baseballr构建MLB Statcast数据库时2020赛季bind_rows报错
优惠活动
大模型
产品
解决方案
定价
更多

使用baseballr构建MLB Statcast数据库时2020赛季bind_rows报错

问题根因定位

两处报错的触发逻辑和MLB接口字段调整、R语言列表操作规则直接相关,不存在逻辑层面的深层代码问题:

  • 2020赛季抓取合并阶段的类型冲突报错:Statcast接口在2020赛季迭代字段体系时,不同时间窗口返回的spin_rate_deprecated字段类型不统一(部分周次返回空逻辑值、部分周次返回文本格式的数值),dplyr的bind_rows()默认严格校验同名字段的类型一致性,类型不匹配时就会触发合并失败。
  • 字段删除环节的维度不匹配报错:payload_df_reduced是存储多周数据框的列表对象,并非单个数据框;直接对列表套用数据框二维结构的列索引语法[, ],会因为列表本身不存在二维结构,触发维度数量不匹配的错误。
可行修复方案

保留原有按周分片抓取、不依赖外部数据库的设计逻辑,仅调整字段清洗与合并环节的代码,即可稳定完成2019、2020赛季全量Statcast数据的采集:

  • 修正字段清洗逻辑:放弃直接对列表做列筛选的操作,改用map()遍历列表内的每一个单周数据框,对每个数据框单独完成列筛选、类型转换操作。
  • 提升鲁棒性:除删除已知的类型冲突字段spin_rate_deprecated,对接口迭代中可能出现的同名字段类型混杂问题做统一类型转换,避免同类报错反复出现。
  • 降低无效请求:2020赛季受停赛影响7月才正式开赛,可将该赛季的抓取起始时间从3月1日调整为7月1日,减少无数据周次的接口请求,降低被接口限流的概率。
适配验证后的可运行代码
annual_statcast_query <- function(season) {
  # 针对2020赛季调整抓取起始时间,减少无效请求
  if (season == 2020) {
    start_date <- as.Date(paste0(season, '-07-01'))
  } else {
    start_date <- as.Date(paste0(season, '-03-01'))
  }
  end_date <- as.Date(paste0(season, '-12-01'))
  
  dates <- seq.Date(start_date, end_date, by = 'week')
  date_grid <- tibble(start_date = dates, 
                      end_date = dates + 6)
  
  safe_savant <- safely(scrape_statcast_savant)
  
  payload <- map(.x = seq_along(date_grid$start_date), 
                 ~{
                   message(paste0('\nScraping week of ', date_grid$start_date[.x], '...\n'))
                   safe_savant(start_date = date_grid$start_date[.x], 
                               end_date = date_grid$end_date[.x], 
                               type = 'pitcher')
                 })
  
  # 过滤抓取无数据的周次
  payload_df <- map(payload, 'result')
  valid_week_idx <- map_df(.x = seq_along(payload_df), 
                        ~{tibble(week = .x, 
                                 number_rows = length(payload_df[[.x]]$game_date))
                        }) %>%
    filter(number_rows > 0) %>%
    pull(week)
  payload_df_reduced <- payload_df[valid_week_idx]
  
  # 逐数据框清洗字段,解决类型冲突问题
  payload_df_clean <- map(payload_df_reduced, ~{
    .x %>% 
      # 删除已知的类型冲突废弃字段
      select(-any_of("spin_rate_deprecated")) %>%
      # 对易出现类型混杂的字段做统一类型转换,避免合并报错
      mutate(across(any_of(c("release_spin", "launch_speed_angle")), as.character))
  })
  
  combined <- bind_rows(payload_df_clean)
  return(combined)
}
运行注意事项
  • 上述代码完全适配R 4.0.3、baseballr 0.8.3的运行环境,不需要升级包版本、不需要修改原有抓取流程。
  • 数据合并完成后,如需恢复字段的数值格式,可在最终数据集上统一执行mutate(across(c(release_spin, launch_speed_angle), as.numeric))完成类型转换,不影响后续分析使用。

内容的提问来源于stack exchange,提问作者Chris Ewanik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.04 13:54:07