首页 > 解决方案 > 使用 BaseballR 包创建 statcast 数据库的问题

问题描述

我正在尝试创建一个包含所有 MLB statcast 结果的数据库。为此,我正在使用baseballrBill Petti https://billpetti.github.io/2020-05-26-build-statcast-database-rstats-version-2.0/制作的包。我没有连接到 SQL 数据库,而只是在 R 中创建了一个数据框。我想收集 2019 年和 2020 年的所有 statcast 数据。首先,我加载了必要的包。

library(baseballr)
library(tidyverse)

然后我执行了这个annual_statcast_query函数:

annual_statcast_query <- function(season) {
  
  dates <- seq.Date(as.Date(paste0(season, '-03-01')),
                    as.Date(paste0(season, '-12-01')), 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'))
                   
                   payload <- safe_savant(start_date = date_grid$start_date[.x], 
                                          end_date = date_grid$end_date[.x], type = 'pitcher')
                   
                   return(payload)
                 })
  
  payload_df <- map(payload, 'result')
  
  number_rows <- map_df(.x = seq_along(payload_df), 
                        ~{number_rows <- tibble(week = .x, 
                                                number_rows = length(payload_df[[.x]]$game_date))}) %>%
    filter(number_rows > 0) %>%
    pull(week)
  
  payload_df_reduced <- payload_df[number_rows]
  
  combined <- payload_df_reduced %>%
    bind_rows()
  
  return(combined)
  
}

当我运行他的 2019 赛季代码时payload <- annual_statcast_query(2019),我可以毫无问题地抓取数据。但是,当我在 2020 年尝试时payload <- annual_statcast_query(2020)遇到了错误:

Error: Can't combine `spin_rate_deprecated` <logical> and `spin_rate_deprecated` <character>.

这个错误出现在annual_statcast_query函数的最后一部分:

  combined <- payload_df_reduced %>%
    bind_rows()

阅读 statcast 文档(https://baseballsavant.mlb.com/csv-docs)时,该变量似乎spin_rate_depreceated已替换为release_spin. 也许这就是我遇到此错误的原因。我的分析不需要这个变量,而且我所做的错误跟踪很明显,解决问题超出了我作为大学生的技能范围。

> rlang::last_error()
<error/vctrs_error_incompatible_type>
Can't combine `spin_rate_deprecated` <logical> and `spin_rate_deprecated` <character>.
Backtrace:
  1. global::annual_statcast_query(2020)
  3. dplyr::bind_rows(.)
  4. vctrs::vec_rbind(!!!dots, .names_to = .id)
  6. vctrs::vec_default_ptype2(...)
  7. vctrs:::vec_ptype2_df_fallback(x, y, opts)
  8. vctrs:::vec_ptype2_params(...)
  9. vctrs:::vec_ptype2_opts(x, y, opts = opts, x_arg = x_arg, y_arg = y_arg)
 11. vctrs::vec_default_ptype2(...)
 12. vctrs::stop_incompatible_type(...)
 13. vctrs:::stop_incompatible(...)
 14. vctrs:::stop_vctrs(...)
Run `rlang::last_trace()` to see the full context.
> rlang::last_trace()
<error/vctrs_error_incompatible_type>
Can't combine `spin_rate_deprecated` <logical> and `spin_rate_deprecated` <character>.
Backtrace:
     x
  1. +-global::annual_statcast_query(2020)
  2. | \-payload_df_reduced %>% bind_rows()
  3. \-dplyr::bind_rows(.)
  4.   \-vctrs::vec_rbind(!!!dots, .names_to = .id)
  5.     \-(function () ...
  6.       \-vctrs::vec_default_ptype2(...)
  7.         \-vctrs:::vec_ptype2_df_fallback(x, y, opts)
  8.           \-vctrs:::vec_ptype2_params(...)
  9.             \-vctrs:::vec_ptype2_opts(x, y, opts = opts, x_arg = x_arg, y_arg = y_arg)
 10.               \-(function () ...
 11.                 \-vctrs::vec_default_ptype2(...)
 12.                   \-vctrs::stop_incompatible_type(...)
 13.                     \-vctrs:::stop_incompatible(...)
 14.                       \-vctrs:::stop_vctrs(...)

因此,我尝试在绑定行操作之前从我的数据库中删除此变量以避免错误。

combined <- payload_df_reduced %>%
    payload_df_reduced[ , !names(payload_df_reduced) %in% c("spin_rate_deprecated")] %>%
    bind_rows()

但是,这返回了错误消息:

Error in .[payload_df_reduced, , !names(payload_df_reduced) %in% c("spin_rate_deprecated")] : 
  incorrect number of dimensions

packageVersion("baseballr") [1] ‘0.8.3’ 在 R 4.03上运行

如果有人可以帮助我找到一种方法来做到这一点,那就太棒了。我对如何获取这些数据并不挑剔,所以如果有人有想法,我会全神贯注。太感谢了!

标签: rdplyr

解决方案


要从 data.frame 中删除一列,您应该这样做:

payload_df_reduced %>%
    select(-c(spin_rate_deprecated))

或者如果使用你现在的方式应该是这样的

payload_df_reduced[ , !names(payload_df_reduced) %in% c("spin_rate_deprecated")]

您当前的代码不起作用,因为它的语法不正确。

看来您的 payload_df_reduced 是一个 data.frame 列表,而不是一个 data.frame。我试图运行您的代码,但似乎您还有其他功能,因此无法重现。这是您可能需要稍微调整的理论代码。

combined <- map(payload_df_reduced, select, -c(spin_rate_deprecated)) %>%
  bind_rows()

推荐阅读