chris_chris
chris_chris

Reputation: 13

R Parsing output from JSON API

I want to retrieve data from IMF JSON RESTful Web Service API. I have found a dataset name and series code, so I submit a following request, usinng httr2 pacakge:

library(httr2)
library(tidyverse)
req <- request("http://dataservices.imf.org/REST/SDMX_JSON.svc/CompactData/IFS/PCPI_IX?startPeriod=2015&endPeriod=2020") %>% 
  req_perform()

As a result I get a list of 7 items.

How should I parse this output to get actual data? In the body item in the response there're no actual numbers. I've tried to use fromJSON from the jsonlite library but it gives me an error (Argument 'txt' must be a JSON string, URL or file).

library(jsonlite)
req <- request("http://dataservices.imf.org/REST/SDMX_JSON.svc/CompactData/IFS/PCPI_IX?startPeriod=2015&endPeriod=2020") %>% 
  req_perform() %>% 
  fromJSON()

Upvotes: 1

Views: 85

Answers (2)

ismirsehregal
ismirsehregal

Reputation: 33540

There is no need to switch to {httr}

httr is superseded: only changes necessary to keep it on CRAN will be made. We recommend using httr2 instead.

Source: https://httr.r-lib.org/

You can use httr2::resp_body_json

library(httr2)
req <- request("http://dataservices.imf.org/REST/SDMX_JSON.svc/CompactData/IFS/PCPI_IX?startPeriod=2015&endPeriod=2020")
resp <- req |> req_perform()
parsed_body <- resp_body_json(resp, simplifyVector = TRUE)
parsed_body

Please see this related article.

Edit: For future readers: You might want to set simplifyVector = TRUE (coerce JSON arrays containing only primitives into an atomic vector) or simplifyDataFrame = TRUE (coerce JSON arrays containing only records (JSON objects) into a data.frame) in resp_body_json which is passed to the underlying jsonlite::fromJSON call.

Upvotes: 2

Ifeanyi Idiaye
Ifeanyi Idiaye

Reputation: 1118

You can use httr instead:

library(httr)
library(jsonlite)

res <- GET("http://dataservices.imf.org/REST/SDMX_JSON.svc/CompactData/IFS/PCPI_IX?startPeriod=2015&endPeriod=2020")

data <- content(res, as = "text", encoding = "UTF-8")

data_list <- fromJSON(data)

data_list

$CompactData
$CompactData$`@xmlns:xsi`
[1] "http://www.w3.org/2001/XMLSchema-instance"

$CompactData$`@xmlns:xsd`
[1] "http://www.w3.org/2001/XMLSchema"

$CompactData$`@xsi:schemaLocation`
[1] "http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message https://registry.sdmx.org/schemas/v2_0/SDMXMessage.xsd http://dataservices.imf.org/compact/IFS http://dataservices.imf.org/compact/IFS.xsd"

$CompactData$`@xmlns`
[1] "http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message"

$CompactData$Header
$CompactData$Header$ID
[1] "793c6858-2fb3-4af1-9612-637fd135ad32"

$CompactData$Header$Test
[1] "false"

$CompactData$Header$Prepared
[1] "2024-12-03T07:30:41"

$CompactData$Header$Sender
$CompactData$Header$Sender$`@id`
[1] "1C0"

$CompactData$Header$Sender$Name
$CompactData$Header$Sender$Name$`@xml:lang`
[1] "en"

$CompactData$Header$Sender$Name$`#text`
[1] "IMF"

$CompactData$Header$Sender$Contact
$CompactData$Header$Sender$Contact$URI
[1] "http://www.imf.org"

$CompactData$Header$Sender$Contact$Telephone
[1] "+ 1 (202) 623-6220"

$CompactData$Header$Receiver
$CompactData$Header$Receiver$`@id`
[1] "ZZZ"

$CompactData$Header$DataSetID
[1] "IFS"

$CompactData$DataSet
$CompactData$DataSet$`@xmlns`
[1] "http://dataservices.imf.org/compact/IFS"

Upvotes: 0

Related Questions