You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法向R函数传入eventid列表?如何批量调用API生成tibble

批量调用API并合并结果的解决方案

已知目标API仅支持单次传入一个eventId,单个调用函数可正常返回数据,但批量传入ID列表时出现错误,需实现批量调用并将所有响应结果合并为一个tibble。

原函数代码

my_func <- function(sport,
                eventId = eventids,
                apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxx",
                regions = "us",
                markets = "alternate_spreads",
                odds_format = "american",
                date_format = "iso"){
    
    base_url = glue::glue("https://xxx.xxx-xxx-xxx.xxx/xx/xxxxxx/{sport}/xxxxxx/{eventId}/odds")
    
    query_params <- list(apiKey = apiKey,
                         sport = sport,
                         eventId = eventId,
                         regions = regions, 
                         markets = markets,
                         oddsFormat = odds_format,
                         dateFormat = date_format)
    
    endpoint <- httr::modify_url(base_url, query = query_params)
    
    resp <- fromJSON(endpoint) %>% 
            as_tibble(validate = F) %>% 
            unnest(cols = bookmakers) %>% 
            rename("bookmaker_key" = "key") %>% 
            unnest(cols = markets) %>% 
            unnest(cols = outcomes)
    
    return(resp)
}

尝试过的方法及对应错误

  • 传入tibble格式的ID列表:

    eventids <- tibble(id = c("xxxxxxxxxxxxxx57adaf06d2660af34", "xxxxxxxxxxx7aa5a4bce731a0"))
    my_func('basketball')
    

    错误信息:

    Error in open.connection(con, "rb") : 
    cannot open the connection to 'https://xxx.xxx-xxxx-xx/sports/basketball/events/truncated?
    In addition: Warning message:
    In open.connection(con, "rb") :
    cannot open URL 'https://xxx.xxx-xxxx-xx/sports/basketball/events/truncated?
    
    HTTP status was '422 Unknown Error'
    
  • 传入向量格式的ID列表:

    eventids <- c("xxxxxxxxxxxxxx57adaf06d2660af34", "xxxxxxxxxxx7aa5a4bce731a0")
    my_func('basketball')
    

    错误信息:

    Error in parse_url(url) : length(url) == 1 is not TRUE
    
  • 用paste拼接ID字符串:

    eventids1 = paste(eventids, collapse = ",")
    my_func('basketball', eventId = eventids1)
    

    仍触发上述parse_url错误。

  • 用purrr::map批量调用:

    map(eventids, my_func)
    # 或
    map(eventids, ~my_func(sport = "basketball", eventId = .x))
    

    错误信息:

    Error in `map()`:
    ℹ In index: 1.
    ℹ With name: id.
    Caused by error in `parse_url()`:
    ! length(url) == 1 is not TRUE
    

解决方案

步骤1:修正函数,确保仅处理单个eventId

原函数在生成base_url时,若传入多个ID会生成多段URL,导致后续httr::modify_url报错。需强制函数仅接收单个ID,并添加参数校验:

my_func <- function(sport,
                eventId,  # 移除默认值,强制传入单个ID
                apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxx",
                regions = "us",
                markets = "alternate_spreads",
                odds_format = "american",
                date_format = "iso"){
    
    # 校验eventId为单个字符串
    if(length(eventId) != 1) stop("eventId must be a single character string")
    
    base_url = glue::glue("https://xxx.xxx-xxx-xxx.xxx/xx/xxxxxx/{sport}/xxxxxx/{eventId}/odds")
    
    query_params <- list(apiKey = apiKey,
                         sport = sport,
                         eventId = eventId,
                         regions = regions, 
                         markets = markets,
                         oddsFormat = odds_format,
                         dateFormat = date_format)
    
    endpoint <- httr::modify_url(base_url, query = query_params)
    
    # 明确指定包名,避免命名冲突
    resp <- jsonlite::fromJSON(endpoint) %>% 
            dplyr::as_tibble(validate = F) %>% 
            tidyr::unnest(cols = bookmakers) %>% 
            dplyr::rename("bookmaker_key" = "key") %>% 
            tidyr::unnest(cols = markets) %>% 
            tidyr::unnest(cols = outcomes)
    
    return(resp)
}

步骤2:用purrr::map_dfr批量调用并合并结果

map_dfr会自动将每个API调用的结果行绑定为一个tibble:

# 若eventids是tibble,先提取ID向量
event_ids_vec <- eventids$id

# 批量调用并合并结果
final_result <- purrr::map_dfr(event_ids_vec, ~my_func(sport = "basketball", eventId = .x))

可选:添加错误容错机制

若部分eventId可能无效,用purrr::possibly包裹函数,避免单个ID调用失败导致整个批量任务中断:

# 创建容错版函数,调用失败时返回空tibble
safe_my_func <- purrr::possibly(my_func, otherwise = dplyr::tibble())

# 批量调用
final_result <- purrr::map_dfr(event_ids_vec, ~safe_my_func(sport = "basketball", eventId = .x))

内容的提问来源于stack exchange,提问作者Aaron Morris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 19:48:17