【问题标题】:How Do I Consume an Array of JSON Objects using Plumber in R如何在 R 中使用 Plumber 使用 JSON 对象数组
【发布时间】:2018-07-17 23:02:21
【问题描述】:

我最近一直在用 R 中的 Plumber 进行试验,当我使用 POST 请求传递以下数据时,我取得了成功;

{"Gender": "F", "State": "AZ"}

这让我可以编写如下函数来返回数据。

#* @post /score
    score <- function(Gender, State){
      data <- list(
        Gender = as.factor(Gender)
        , State = as.factor(State))

      return(data)
      }

但是,当我尝试 POST 一个 JSON 对象数组时,我似乎无法通过函数访问数据

[{"Gender":"F","State":"AZ"},{"Gender":"F","State":"NY"},{"Gender":"M","State":"DC"}]

我收到以下错误

{
    "error": [
        "500 - Internal server error"
    ],
    "message": [
        "Error in is.factor(x): argument \"Gender\" is missing, with no default\n"
    ]
}

有人知道 Plumber 是如何解析 JSON 的吗?我不确定如何访问字段并将其分配给向量以对数据进行评分。

提前致谢

【问题讨论】:

  • 我不认为这会在今天得到很好的处理。我在这里创建了一个问题。 github.com/trestletech/plumber/issues/236。一种解决方法是在对象内命名数组,例如{arr: ["Gender": ...,然后您可以通过arr 参数访问它
  • 谢谢。命名数组暂时解决了这个问题。
  • 在这里完成疯狂的猜测 - 如果你将你的函数定义为 score &lt;- function(...) 然后相应地解开里面的点会发生什么

标签: json r api plumber


【解决方案1】:

我在这里看到了两种可能的解决方案。第一个是基于命令行的方法,我假设您正在尝试。我在 Windows 操作系统上对此进行了测试,并使用了基于列的 data.frame 编码,由于 JSON 字符串长度较短,我更喜欢这种编码。确保正确转义引号以避免'argument "..." is missing, with no default' 错误:

curl -H "Content-Type: application/json" --data "{\"Gender\":[\"F\",\"F\",\"M\"],\"State\":[\"AZ\",\"NY\",\"DC\"]}" http://localhost:8000/score
# [["F","F","M"],["AZ","NY","DC"]]

第二种方法是 R 原生的,具有将所有内容集中在一个位置的优势:

library(jsonlite)
library(httr)

## sample data
lst = list(
  Gender = c("F", "F", "M")
  , State = c("AZ", "NY", "DC")
)

## jsonify
jsn = lapply(
  lst
  , toJSON
)

## query
request = POST(
  url = "http://localhost:8000/score?"
  , query = jsn # values must be length 1
)

response = content(
  request
  , as = "text"
  , encoding = "UTF-8"
)

fromJSON(
  response
)
#      [,1]                    
# [1,] "[\"F\",\"F\",\"M\"]"   
# [2,] "[\"AZ\",\"NY\",\"DC\"]"

请注意,httr::POST() 需要一个长度为 1 的值的列表作为查询输入,因此数组数据应事先进行 json 化。如果您想完全避免额外的包导入,一些 system()sprintf() 等魔术应该可以解决问题。

最后,这是我的 plumber 端点(住在R/plumber.R 并浓缩了一点):

#* @post /score
score = function(Gender, State){
  lapply(
    list(Gender, State)
    , as.factor
  )
}

以及启动 API 的代码:

pr = plumber::plumb("R/plumber.R")
pr$run(port = 8000)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 2020-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多