2017-02-20 3 views
4

Мне удалось получить некоторые данные из статистики Швеции, используя веб-сайт api. Ответы на этот вопрос решены большинством моих проблем.Загрузить данные из Статистического управления Швеции. Шведские символы в запросе

How do I POST a JSON formatted request to GET JSON data from a URL in R into the data.frame in a less verbose manner?

Но у меня еще есть две проблемы.

Если у меня есть персонажи с умлаутами в моем json-вопросе (например, «Å», «Ä», «Ö»), я получаю ответ «404» с сервера.

Я пытаюсь загрузить данные из этой таблицы:

Population 16+ years (RAMS) by region, employment, age and sex. Year 2004 - 2015

(Вы можете получить запрос к API на веб-сайте, если вы нажмите кнопку «Продолжить», а затем «апи для этой таблицы », но вы должны изменить формат ответа от„пикселей“на„“JSON)

Этот код работает:.

library(jsonlite) 
library(httr) 

bodytxt <- '{ 
    "query": [ 
{ 
    "code": "Region", 
    "selection": { 
    "filter": "vs:RegionKommun07", 
    "values": [ 
    "0114", 
    "1280" 
    ] 
    } 
}, 
    { 
    "code": "Alder", 
    "selection": { 
    "filter": "item", 
    "values": [ 
    "16-19" 
    ] 
    } 
    }, 
    { 
    "code": "Tid", 
    "selection": { 
    "filter": "item", 
    "values": [ 
    "2015" 
    ] 
    } 
    } 
    ], 
    "response": { 
    "format": "json" 
    } 
    }' 


req <- POST("http://api.scb.se/OV0104/v1/doris/en/ssd/START/AM/AM0207/AM0207H/BefSyssAldKonK", 
      body = bodytxt, encode = "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 <- fromJSON(json) 
print(object) 

но если изменить запрос таким образом, он включает «...», он не работает. Пример:

bodytxt <- '{ 
    "query": [ 
    { 
     "code": "Region", 
     "selection": { 
     "filter": "vs:RegionKommun07", 
     "values": [ 
      "0114", 
      "1280" 
      ] 
     } 
    }, 
    { 
     "code": "Sysselsattning", 
     "selection": { 
     "filter": "item", 
     "values": [ 
      "FÖRV" 
      ] 
     } 
    }, 
    { 
     "code": "Alder", 
     "selection": { 
     "filter": "item", 
     "values": [ 
      "16-19" 
      ] 
     } 
    }, 
    { 
     "code": "Tid", 
     "selection": { 
     "filter": "item", 
     "values": [ 
      "2015" 
      ] 
     } 
    } 
    ], 
    "response": { 
    "format": "json" 
    } 
}' 

Другая проблема у меня в том, что, насколько я понимаю, это должно быть возможно изменить JSon запрос в список и включить список в вызове на сервер, но я получаю "404" -ошибка. Пример:

body_list <- fromJSON(bodytxt) 
req <- POST("http://api.scb.se/OV0104/v1/doris/en/ssd/START/AM/AM0207/AM0207H/BefSyssAldKonK", 
      body = body_list, encode = "json") 

Что я делаю неправильно?

Ps! Я знаю, что существует отличный пакет на CRAN, который называется pxweb, который очень прост в использовании для загрузки данных из статистики Швеции. Но я хочу узнать, что api и pxwed не позволяют мне пропускать измерения в запросе.

Система: сценарий Windows 7, r, сохраненный в кодировке utf-8.

ответ

3

Попробуйте эти параметры для fromJSON():

library(httr) 
library(jsonlite) 

ваши данные:

bodytxt <- '{ 
    "query": [ 
    { 
     "code": "Region", 
     "selection": { 
     "filter": "vs:RegionKommun07", 
     "values": [ 
      "0114", 
      "1280" 
      ] 
     } 
    }, 
    { 
     "code": "Sysselsattning", 
     "selection": { 
     "filter": "item", 
     "values": [ 
      "FÖRV" 
      ] 
     } 
    }, 
    { 
     "code": "Alder", 
     "selection": { 
     "filter": "item", 
     "values": [ 
      "16-19" 
      ] 
     } 
    }, 
    { 
     "code": "Tid", 
     "selection": { 
     "filter": "item", 
     "values": [ 
      "2015" 
      ] 
     } 
    } 
    ], 
    "response": { 
    "format": "json" 
    } 
}' 

Модифицированный fromJSON() преобразование:

query <- jsonlite::fromJSON(bodytxt, 
          simplifyVector=FALSE, 
          simplifyDataFrame=FALSE) 

же позвоню сделал (добавил verbose() для моей пользы, кроме вас может удалить это):

URL <- "http://api.scb.se/OV0104/v1/doris/en/ssd/START/AM/AM0207/AM0207H/BefSyssAldKonK" 
req <- POST(URL, body=query, encode="json", verbose()) 

Результат:

content(req, simplifyDataFrame=TRUE) 

## Warning: JSON string contains (illegal) UTF8 byte-order-mark! 

## $columns 
##    code      text type 
## 1   Region      region d 
## 2 Sysselsattning   employment status d 
## 3   Alder       age d 
## 4   Tid      year t 
## 5  AM0207F2 Population 16+ years (RAMS) c 
## 
## $comments 
## list() 
## 
## $data 
##      key values 
## 1 0114, FÖRV, 16-19, 2015 379 
## 2 1280, FÖRV, 16-19, 2015 1443 

Предупреждение связано с тем, что сервер API отправляет метку порядка байтов назад с результатом (это сервер Microsoft, так они вроде мозга когда дело доходит до этого). jsonlite (бит внутри content(), который делает преобразование) может справиться с этим.

+0

Работает отлично! Благодаря!Итак, похоже, что это не проблема кодирования символов, или конверсия из json в список из функции fromJSON() каким-либо образом изменяет кодировку? – ChristianL

+0

В вызове 'fromJSON()' никакого искажения не происходит. Именно так конвертировался JSON перед отправкой в ​​API. Он пытается быть «полезным» для работы по анализу данных (и обычно по умолчанию), но обычно это не то, что другие программы ожидают. Вы заслуживаете похвалы за вспашку. Дополнительная работа по настройке вызовов параметров API - отличный пример для многих других, которые, без сомнения, будут запрашивать, как это сделать в будущем. – hrbrmstr

+1

Я просто понял, что если я выберем «csv» в качестве формата в json-запросе в теле POST, приведенный выше код вернет хорошо отформатированный тибет. Возможно, хорошо знать, хочет ли кто-нибудь использовать код. – ChristianL

Смежные вопросы