2014-11-01 1 views
2

Я написал следующий код в R, чтобы начать использовать API запросов данных. Это обычный веб-сервис JSON API.Как отправить POST отформатированный запрос JSON для получения данных GET JSON из URL-адреса в R в data.frame менее подробным образом?

library(RJSONIO) 
library(RCurl) 
library(httr) 

r <- POST("http://api.scb.se/OV0104/v1/doris/sv/ssd/START/PR/PR0101/PR0101A/KPIFastM2", 
      body = '{ "query": [], "response": { "format": "json" } }') 
stop_for_status(r) 
a<-content(r, "text", "application/json", encoding="UTF-8") 
cat(a, file = "test.json") 
x<-fromJSON(file("test.json", "r")) 
mydf<-do.call(rbind, lapply(x$data, data.frame)) 
colnames(mydf)<-c("YearMonth", "CPI") 

В основном это инициировало GET reuest для URL с помощью HTTR, а затем преобразовать полученные данные JSON в структуру R с помощью fromJSON. Запрос JSON выглядит следующим образом:

{ "query": [], "response": { "format": "json" } } 

В самом деле мой код получает данные в data.frame, как я хотел, чтобы это, но это мучительно многословным, и я отказываюсь верить, что все эти линии необходимы для достижения желаемый результат. Разумеется, желаемый результат - это mydf data.frame.

Так к моему вопросу: Каков самый короткий и самый правильный способ получить данные из веб-службы в data.frame?

Cheers, Майкл

+0

JSON кажется, что это не правильно отформатирован, например, 'jsonlite :: Validate (содержание (г, "Текст"))' выдает ошибку. Если бы он был действительным JSON, он легко анализировал бы с помощью только 'content (r," text ")', тогда 'jsonlite :: fromJSON()' может разбираться с 'data.frame', если возможно для вас – sckott

ответ

6

Есть две проблемы. Один из них заключается в том, что вы не используете jsonlite :-) Другой заключается в том, что ваш источник JSON, кажется, префикс blob с символом U+FEFFByte order Mark, что делает JSON недействительным. RFC7159 говорит:

Реализации НЕ ДОЛЖНЫ добавлять знак порядка байтов в начало текста JSON. В интересах интероперабельности реализации, которые анализируют тексты JSON, МОГУТ игнорировать присутствие байтового байта, а не рассматривать его как ошибку.

Так что scb.se не форматирует их JSON правильно. В любом случае, попробуйте следующее:

library(jsonlite) 
library(httr) 

req <- POST("http://api.scb.se/OV0104/v1/doris/sv/ssd/START/PR/PR0101/PR0101A/KPIFastM2", 
    body = '{ "query": [], "response": { "format": "json" } }') 
stop_for_status(req) 
json <- content(req, "text") 


# JSON starts with an invalid character: 
validate(json) 
json <- substring(json, 2) 
validate(json) 

# Now we can parse 
object <- jsonlite::fromJSON(json) 
print(objects) 
+0

Действительно вы правы , Вначале была скрытая присоска. Странно для такого большого поставщика данных для f * ck что-то вроде этого. –

+2

FYI новая версия jsonlite имеет исправление, чтобы игнорировать спецификацию. – Jeroen