r - 创建函数/循环

标签 r function purrr httr

我有从 API 中提取的数据,但为此目的,我将使用虚拟数据:

test <- structure(list(Id = 201:203, firstname = c("Jackie", "Liz", "Jack"), 
                       lastname = c("Jormpjomp", "Lemon", "Donaghy"), 
                       address = c("4 Main St.", "5 Main St.", "6 Main St."), 
                       zip = c(89044L, 60301L, 85281L), 
                       dob = c(NA, "7/1/88", "2/13/90"), 
                       phone = c("333-333-3333","4444", "555-555-5555"), 
                       statecode = c("NV", "WI", "AZ")), 
                  class = "data.frame", 
                  row.names = c(1, 2, 3))
                                                                
首先,我将所有需要的变量隔离为它们自己的值:
Ids <- test$Id
firstnames <- test$firstname
lastnames <- test$lastname
addresses <- test$address
zips <- test$zip
dobs <- test$dob
phones <- test$phone
然后我创建了一个字符向量来添加到最终的 API 调用中:
data_upsert = paste0(
    '{ "Id": ', Ids, ',
  "firstName": "', firstnames, '",
  "lastname": "', lastnames, '",
  "dateOfBirth": "', dobs, '",
  "phones": [ 
               { "phoneNumber": "', phones, '" } ], 
               "addresses": [ 
               { "addressLine1": "', addresses, '", 
               "zipOrPostalCode": "', zips, '",
               } ] } 
  ')
然后我为我的标题创建一个变量 - 这将在整个过程中保持不变
headers_upsert = c(
  `Accept` = 'application/json',
  `Authorization` = 'Basic JFOJDIFvdhSOFOHAD83820348voqpTOESV==',
  `Content-Type` = 'application/json'
)
最后,我完成了 API 调用,如下所示:
upsert <- httr::POST(url = 'https://api.secure.com/v1/people/Create', httr::add_headers(.headers=headers_upsert), body = data_upsert)
运行创建的响应如下所示:
Response [https://api.secure.com/v1/people/Create]
  Date: 2021-08-31 20:28
  Status: 201
  Content-Type: application/json; charset=utf-8
  Size: 58 B
{
  "Id": 222323178,
  "status": "UnmatchedStored"
然后我想以表格形式存储这个响应:
resContent <- content(res, as="text")

resJSON <- jsonlite::fromJSON(resContent)

resTable <- as.data.frame(resJSON)
如果你运行上面的所有内容,它显然只适用于 test 中的第一行。 ,但我正在寻找一种时尚的方式来编写一个函数和循环:
A) 为所有三行运行 API 调用
B) 创建一个包含所有三个响应的表
编辑:基于 Bing 的回复:
运行 Bing 的响应后,它完成了第一部分,但问题在于最后制作表格。response 的结果看起来像这样:
[[1]]
Response [https://api.secure.com/v1/people/111322450]
  Date: 2021-09-01 15:02
  Status: 200
  Content-Type: application/json; charset=utf-8
  Size: 1.56 kB
{
  "Id": 111322450,
  "firstName": "Jackie",
  "lastName": "Jormpjomp",
  "middleName": null,
  "suffix": null,
  "title": "Mr.",
  "contactMode": "Person",
  "organizationContactCommonName": null,
  "organizationContactOfficialName": null,
...

[[2]]
Response [https://api.secure.com/v1/people/findOrCreate/]
  Date: 2021-09-01 15:02
  Status: 201
  Content-Type: application/json; charset=utf-8
  Size: 58 B
{
  "Id": 111323215,
  "status": "UnmatchedStored"

[[3]]
Response [https://api.secure.com/v1/people/findOrCreate/]
  Date: 2021-09-01 15:02
  Status: 201
  Content-Type: application/json; charset=utf-8
  Size: 58 B
{
  "Id": 111323216,
  "status": "UnmatchedStored"
当我运行时:
resContent=map(response , httr::content, as="text")

resJSON <- map(resContent, jsonlite::fromJSON)

resTable <- map(resJSON, as.data.frame)
resTable仍然存储为一个列表,看起来像这样 编辑 :
$data
$data[[1]]
Response [https://api.secure.com/v1/people/111322450]
  Date: 2021-09-01 18:24
  Status: 200
  Content-Type: application/json; charset=utf-8
  Size: 1.58 kB
{
  "Id": 111322450,
  "firstName": "Jackie",
  "lastName": "Jormpjomp",
  "middleName": null,
  "suffix": null,
  "title": null,
  "contactMode": "Person",
  "organizationContactCommonName": null,
  "organizationContactOfficialName": null,
...

$data[[2]]
Response [https://api.secure.com/v1/people/findOrCreate/]
  Date: 2021-09-01 18:24
  Status: 201
  Content-Type: application/json; charset=utf-8
  Size: 58 B
{
  "Id": 111323215,
  "status": "UnmatchedStored"

$data[[3]]
Response [https://api.secure.com/v1/people/findOrCreate/]
  Date: 2021-09-01 18:24
  Status: 201
  Content-Type: application/json; charset=utf-8
  Size: 58 B
{
  "Id": 111323216,
  "status": "UnmatchedStored"


$args
$args[[1]]
[1] "map(jsonlite::fromJSON)"
attr(,"type")
[1] "map"

$args[[2]]
[1] "map(as.data.frame)"
attr(,"type")
[1] "map"


attr(,"class")
[1] "jqr"
我需要从每个响应中获得的唯一数据是 Id 编辑 #2
运行以下内容:
resContent=map(response , httr::content)   
    
resTable <- map(resContent, ~.x$Id) %>% as.data.frame()
返回以下错误:
Error in as.data.frame.default(.) : 
  cannot coerce class ‘"jqr"’ to a data.frame

最佳答案

httr::POST 未矢量化。您将需要遍历每一个。您可以使用 lapply或整洁的版本,如:

library(purrr)
response = map(data_upsert,
  ~httr::POST(url = 'https://www.google.com/', 
           httr::add_headers(.headers=headers_upsert), 
           body = .x))
看看这些是否有效。 编辑 :
resContent=map(response , httr::content)   
    
resTable <- map(resContent, ~.x$Id) #%>% as.data.frame()

关于r - 创建函数/循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69005084/

相关文章:

R:多个模型并排的方差分析输出

r - 在 R 中如何用英语获取错误消息

r - 具有完全内置 HTML 的 UI 的 Shiny 应用程序 - ShinyJS 显示/隐藏元素不起作用

r - 将函数应用于矩阵或数据框的每一行

c - main 中的 next 函数和数组的结果是什么?

swift - 由于赋值语句错位,函数总是返回 nil

Rcpp:将矩阵转换为向量

r - 使用 purrr::map 将新列分配给 data.tables 列表

r - 使用 purrr 取消嵌套列表并收集项目

r - 在 mutate 之外使用 nest 和 purrr::map