【问题标题】:Creating a function/loop创建函数/循环
【发布时间】:2021-08-31 20:40:57
【问题描述】:

我从 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 的回复:

运行必应的响应后,它完成了第一部分,但问题在于最后制作表格。

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 仍以列表形式存储,如下所示EDIT

$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

【问题讨论】:

    标签: r function purrr httr


    【解决方案1】:

    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()
    

    【讨论】:

    • 感谢您的回复。它并没有给我我正在寻找的输出。请参阅上面的编辑。
    • 忽略最后一条评论。注意到我在那里有一个包裹并发症。立即编辑。
    • 您的答案的第一部分奏效了!谢谢你。也就是说,第二部分仍然给我带来了问题。你能看看我所做的编辑吗?
    • @SloppySteaks resTable 将是一个列表。你需要用它来做一张桌子。 resTable 长什么样子?
    • 检查我刚刚包含的新编辑!我需要从每个响应中获取的唯一数据是Id。谢谢!
    猜你喜欢
    • 2021-12-21
    • 1970-01-01
    • 2018-11-16
    • 1970-01-01
    相关资源
    最近更新 更多