我正在尝试从数据帧中一次一行构建 GET 请求,其中可能的参数是一个多种多样的大型列表,并且我传递给函数的数据帧可能没有正确命名的列标题。
library(tidyverse)
library(httr2)
dfInput <- structure(list(orig_zip = c("17502", "66616", "M1P2T7"),
orig_ctry = c("USA", "MEX", "CAN")),
row.names = c(NA, 3L), class = "data.frame")
> dfInput
orig_zip orig_ctry
1 17502 USA
2 66616 MEX
3 M1P2T7 CAN
第一个函数显示了从数据帧的每一行获取的所需输出,但在这里我对其进行了硬编码,而不是实际使用我想要的
...
。在编写时选择什么参数没有灵活性,但是 postalcode = df$orig_zip[i], country = df$orig_ctry[i]
是我需要的代码类型 req_url_query()
:
f1 <- function(df, ...){
req <- httr2::request("http://some/base/url")
for (i in 1:nrow(df)){
req %>%
req_url_query(postalcode = df$orig_zip[i], country = df$orig_ctry[i]) %>%
req_dry_run()
}
}
> f1(dfInput, postalcode = orig_zip, country = orig_ctry)
GET /base/url?postalcode=17502&country=USA HTTP/1.1
***OUTPUT TRUNCATED***
GET /base/url?postalcode=66616&country=MEX HTTP/1.1
***OUTPUT TRUNCATED***
GET /base/url?postalcode=M1P2T7&country=CAN HTTP/1.1
***OUTPUT TRUNCATED***
此函数使用
...
,但我在函数调用中传递实际值,显然这不会通过数据帧进行。
f2 <- function(df, ...){
req <- httr2::request("http://some/base/url")
for (i in 1:nrow(df)){
req %>%
req_url_query(...) %>%
req_dry_run()
}
}
> f2(dfInput, postalcode = "17502", country = "USA")
GET /base/url?postalcode=17502&country=USA HTTP/1.1
***OUTPUT TRUNCATED***
GET /base/url?postalcode=17502&country=USA HTTP/1.1
***OUTPUT TRUNCATED***
GET /base/url?postalcode=17502&country=USA HTTP/1.1
***OUTPUT TRUNCATED***
我做了一些努力(未全部显示)来尝试各种
rlang
引用功能,直到达到您在下面看到的内容,但我觉得这可能与一些更简单的过程相距太远。
f3 <- function(df, ...){
args <- list2(enexprs(...))
print(args)
a1 <- lapply(args, \(x) paste0(".data$", x, "[i]"))
print(a1)
# req <- httr2::request("http://some/base/url")
# for (i in 1:nrow(df)){
# req %>%
# req_url_query(...) %>%
# req_dry_run()
# }
}
> f3(dfInput, postalcode = orig_zip, country = orig_ctry)
[[1]]
[[1]]$postalcode
orig_zip
[[1]]$country
orig_ctry
[[1]]
[1] ".data$orig_zip[i]" ".data$orig_ctry[i]"
我仍在努力解决这个问题,但在燃烧了几个小时后,我没有得到它,需要一些帮助。我很感激你能提供的任何东西。谢谢你。
...
是必要的,但我是一名 padawanR,而不是 JediR,所以我在这一点上持开放态度。list(postalcode = "17502", country = "USA")
一行 orig_zip
和orig_ctry
,但是下次我使用该函数时,我可能需要从包含列list(address = "1 Infinite Loop", city = "Redmond", state = "TN")
、orig_addr
和orig_city
的数据框中传递orig_state
。因此,我有灵活的函数参数(postalcode
),它必须指向数据框的列名称(orig_zip
),它必须一次指向该列中的一个值(“17502”)。你是怎么做到的?技巧是使用点来构建一个中间数据框,其中
transmute()
仅包含感兴趣的列。
然后使用
!!!
注入行,但由于您是在数据屏蔽上下文之外执行此操作,因此我们需要使用 inject()
显式启用注入。
f <- function(df, ...) {
req <- httr2::request("http://some/base/url")
# Transform to tibble to make sure `[` behaves predictably.
# Also prevents grouped df to disturb behaviour.
# Use `transmute()` to reduce the data frame to passed inputs.
df <- df |> as_tibble() |> transmute(df, ...)
for (i in seq_len(nrow(df))) {
# Inject rows into the query with `!!!`
rlang::inject(
req %>%
req_url_query(!!!df[i, ]) %>%
req_dry_run()
)
}
}
f(dfInput, postalcode = orig_zip, country = orig_ctry)
#> GET /base/url?orig_zip=17502&orig_ctry=USA&postalcode=17502&country=USA HTTP/1.1
#> Host: some
#> User-Agent: httr2/0.2.3 r-curl/5.0.1 libcurl/7.85.0
#> Accept: */*
#> Accept-Encoding: deflate, gzip
#>
#> GET /base/url?orig_zip=66616&orig_ctry=MEX&postalcode=66616&country=MEX HTTP/1.1
#> Host: some
#> User-Agent: httr2/0.2.3 r-curl/5.0.1 libcurl/7.85.0
#> Accept: */*
#> Accept-Encoding: deflate, gzip
#>
#> GET /base/url?orig_zip=M1P2T7&orig_ctry=CAN&postalcode=M1P2T7&country=CAN HTTP/1.1
#> Host: some
#> User-Agent: httr2/0.2.3 r-curl/5.0.1 libcurl/7.85.0
#> Accept: */*
#> Accept-Encoding: deflate, gzip