Good morning all,
I new to R and I am trying to get several from a httr::POST function. Below I send the code:
`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)`
The code works fine if I perform one request at a times. However, I had several IDs that I need to get the link.
When I try to substitute the values of "instrument","event" and "record" in order to try to execute a loop or a apply-like function I get an error message.
The code I tried:
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)
}
The error I get:
"Error in vapply(elements, encode, character(1)) : values must be length 1, but FUN(X[[6]]) result is length 2"
The traceback to error is as follow:
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")
My question is, is that possible to retrieve a batch of those links with an iterative function?
Thank you very much,
Gabriel Pokorny
(Up front: unverified, I don't have a token for that API.)
Two things I'm fixing:
for
loops don't return
anything, and you are overwriting result
each pass through the loop. There are two remedies for this, either using lapply
instead of a for
loop or pre-instantiating a list first and filling each element. I'll show both.
Even though it looks like you intend to iterate over my_list
, a vector of record IDs, you are passing the whole vector in all calls, likely a mistake. Let's iterate over my_list
and use it everywhere.
First, the use of lapply
which is (imo) a clean and easy way to go:
token <- "FC9439DCA5A64714XXXXXXXXXXXXX"
url <- "https://redcap.fmrp.usp.br/api/"
my_list <- c("949_1","949_2")
out <- lapply(my_list, function(one_record) {
formData <- list(token=token,
content='surveyLink',
format='xml',
instrument= "qualidade_de_vida_cervical",
event= "baseline_arm_1",
record= one_record,
returnFormat='xml'
)
response <- httr::POST(url, body = formData, encode = "form")
if (httr::status_code(response) == 200L) {
httr::content(response) %>%
minimal_html() %>%
html_elements("body") %>%
html_text2()
} # else NULL
})
If you prefer the for
loop (it may have some advantages, some subjective), then do this instead:
out <- list()
for (i in seq_along(my_list)) {
one_record <- my_list[[i]]
formData <- list(token=token,
content='surveyLink',
format='xml',
instrument= "qualidade_de_vida_cervical",
event= "baseline_arm_1",
record= one_record,
returnFormat='xml'
)
response <- httr::POST(url, body = formData, encode = "form")
if (httr::status_code(response) == 200L) {
out[[i]] <- httr::content(response) %>%
minimal_html() %>%
html_elements("body") %>%
html_text2()
} # else NULL
}