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

如何用httr::POST批量获取REDCap调查链接?

批量调用REDCap API获取调查链接报错的解决方法

问题描述

作为R语言新手,使用httr::POST调用REDCap API获取单个调查链接的代码可正常运行,但尝试通过循环批量获取多个record对应的链接时出现错误:

Error in vapply(elements, encode, character(1)) : values must be length 1, but FUN(X[[6]]) result is length 2

错误源于POST请求的参数编码,调用栈如下:

6. vapply(elements, encode, character(1))
5. compose_query(body)
4. body_raw(compose_query(body), "application/x-www-form-urlencoded")
3. body_config(body, match.arg(encode))
2. request_build("POST", hu$url, body_config(body, match.arg(encode)), 
as.request(config), ...)
1. httr::POST(url, body = formData, encode = "form")

原单次请求代码:

token <- "FC9439DCA5A64714XXXXXXXXXXXXX"
url <- "https://redcap.fmrp.usp.br/api/"
formData <- list("token"=token,
    content='surveyLink',
    format='xml',
    instrument= "qualidade_de_vida_cervical",
    event= "baseline_arm_1",
    record= "1",
    returnFormat='xml'
)
response <- httr::POST(url, body = formData, encode = "form")
result <- httr::content(response)
result <- minimal_html(result) %>% html_elements("body") %>% html_text2()
return(result)

尝试的批量代码(报错):

my_list <- c("949_1","949_2")
    
for (i in my_list){
    token <- "FC9439DCA5A64XXXXXXXXXXXXXXXX"
    url <- "https://redcap.fmrp.usp.br/api/"
    formData <- list("token"=token,
        content='surveyLink',
        format='xml',
        instrument= "qualidade_de_vida_cervical",
        event= "baseline_arm_1",
        record= my_list,
        returnFormat='xml'
    )
    response <- httr::POST(url, body = formData, encode = "form")
    result <- httr::content(response)
    result <- minimal_html(result) %>% html_elements("body") %>% html_text2()
    return(result) 
}

错误原因

你在循环里犯了两个关键错误:

  • record参数赋值错误:循环中你把整个my_list传给了record,而非当前迭代的元素i,导致record是长度为2的向量。REDCap的surveyLink接口单次请求仅接受单个record值,同时httr的encode="form"要求每个参数都是长度1的元素,这直接触发了编码错误。
  • 循环内过早使用return():return()会直接终止循环和函数运行,第一次迭代就会退出,根本不会处理第二个record。

解决方案

可以通过修正循环或使用迭代函数两种方式实现批量获取,具体如下:

方法1:修正for循环

library(httr)
library(rvest)

token <- "FC9439DCA5A64XXXXXXXXXXXXXXXX"
url <- "https://redcap.fmrp.usp.br/api/"
my_list <- c("949_1","949_2")
survey_links <- character(length(my_list))  # 预先创建存储结果的向量

for (i in seq_along(my_list)) {
    current_record <- my_list[i]
    formData <- list(
        "token" = token,
        content = 'surveyLink',
        format = 'xml',
        instrument = "qualidade_de_vida_cervical",
        event = "baseline_arm_1",
        record = current_record,
        returnFormat = 'xml'
    )
    response <- httr::POST(url, body = formData, encode = "form")
    result <- httr::content(response)
    survey_links[i] <- minimal_html(result) %>% html_elements("body") %>% html_text2()
}

# 查看结果
survey_links

方法2:使用purrr迭代函数

如果习惯函数式编程,用purrr::map()更简洁:

library(httr)
library(rvest)
library(purrr)

token <- "FC9439DCA5A64XXXXXXXXXXXXXXXX"
url <- "https://redcap.fmrp.usp.br/api/"
my_list <- c("949_1","949_2")

get_survey_link <- function(record_id) {
    formData <- list(
        "token" = token,
        content = 'surveyLink',
        format = 'xml',
        instrument = "qualidade_de_vida_cervical",
        event = "baseline_arm_1",
        record = record_id,
        returnFormat = 'xml'
    )
    response <- httr::POST(url, body = formData, encode = "form")
    result <- httr::content(response)
    minimal_html(result) %>% html_elements("body") %>% html_text2()
}

# 批量获取链接
survey_links <- map_chr(my_list, get_survey_link)

# 查看结果
survey_links

注意事项

  • 确保REDCap项目权限允许批量获取调查链接,部分项目可能限制接口调用频率,若遇到限流问题,可在循环中加入Sys.sleep(1)之类的延迟。
  • 始终保护token的安全性,不要将明文token提交到代码仓库或公开场合。

内容的提问来源于stack exchange,提问作者Gabriel Pokorny

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 20:22:54