简体   繁体   English

如何在 R 中使用 Plumber 使用一组 JSON 对象

[英]How Do I Consume an Array of JSON Objects using Plumber in R

I have been experimenting with Plumber in R recently, and am having success when I pass the following data using a POST request;我最近一直在 R 中试验 Plumber,当我使用 POST 请求传递以下数据时取得了成功;

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

This allows me to write a function like the following to return the data.这允许我编写一个如下所示的函数来返回数据。

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

      return(data)
      }

However, when I try to POST an array of JSON objects, I can't seem to access the data through the function但是,当我尝试 POST 一组 JSON 对象时,似乎无法通过该函数访问数据

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

I get the following error我收到以下错误

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

Does anyone have an idea of how Plumber parses JSON?有没有人知道 Plumber 如何解析 JSON? I'm not sure how to access and assign the fields to vectors to score the data.我不确定如何访问字段并将其分配给向量以对数据进行评分。

Thanks in advance提前致谢

I see two possible solutions here.我在这里看到两种可能的解决方案。 The first would be a command line based approach which I assume you were attempting.第一个是基于命令行的方法,我假设您正在尝试。 I tested this on a Windows OS and used column based data.frame encoding which I prefer due to shorter JSON string lengths.我在 Windows 操作系统上对此进行了测试,并使用了基于列的 data.frame 编码,由于 JSON 字符串长度较短,我更喜欢这种编码。 Make sure to escape quotation marks correctly to avoid 'argument "..." is missing, with no default' errors:确保正确转义引号以避免“参数“...”丢失,没有默认错误:

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"]]

The second approach is R native and has the advantage of having everything in one place:第二种方法是 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\"]"

Be aware that httr::POST() expects a list of length-1 values as query input, so the array data should be jsonified beforehand.请注意, httr::POST()需要一个长度为 1 的值列表作为查询输入,因此应事先对数组数据进行 jsonified。 If you want to avoid the additional package imports altogether, some system() , sprintf() , etc. magic should do the trick.如果你想完全避免额外的包导入,一些system()sprintf()等魔术应该可以解决问题。

Finally, here is my plumber endpoint (living in R/plumber.R and condensed a little bit):最后,这是我的管道工端点(住在R/plumber.R并稍微浓缩):

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

and code to fire up the API:以及启动 API 的代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM