2014-05-16 7 views
2

나는 StatBank 덴마크에서 데이터를 가져 오기 위해 몇 가지 기능을 사용하고 있으며, API입니다. 그들은 JSON 호출을 테스트하기 위해 console을 만들었고 dst_get_data 함수에서 JSON을 구문 분석하는 basic_request를 알고 있습니다. 콘솔에서 테스트 했으므로.R httr JSON의 POST가 상태 400을 반환합니다.

"상태 400"오류가 발생하고 "게시 할 때 개체를 제공해야합니다"라는 오류 메시지가 나타납니다.

아래 코드는 재현 가능한 예를 만들어야합니다. 그것은 내가 붙어있는 세 번째 함수 (dst_get_data)입니다.

dst_get_data <- function(request, table, ..., lang = "en", 
         format = "CSV", value_presentation = "Default") { 

    require(httr) 
    require(jsonlite) 

    dst_url <- "http://api.statbank.dk/v1/data" 

    final_request <- list("table" = table, 
         "lang" = lang, 
         "format" = format, 
         "valuePresentation" = value_presentation) 

    data <- POST(url=dst_url, body=final_request, multipart=FALSE) 

    return(data) 

} 

과에 그것을 호출 : 나는 dst_get_data에 변경

dst_meta <- function(table, ..., lang = "en"){ 
    require(jsonlite) 
    require(httr) 

    dkstat_url <- "http://api.statbank.dk/v1/tableinfo" 

    params <- list("lang" = lang, 
       "table" = table, 
       "format" = "JSON") 

    meta <- POST(url=dkstat_url, body=params, multipart=FALSE) 
    meta <- jsonlite::fromJSON(txt=content(meta, as="text"),simplifyDataFrame=TRUE) 
    #meta <- RJSONIO::fromJSON(content=content(meta),asText=TRUE, simplify=TRUE, simplifyWithNames=TRUE) 

    return(meta) 
} 

dst_meta_parse <- function(meta, lang){ 

    basics_names <- c("id", "text", "description", 
        "unit", "updated", "footnote") 

    basics <- meta[names(meta) %in% basics_names] 

    variables <- meta[["variables"]][,c("id", "text")] 

    values <- meta[["variables"]][,"values"] 
    names(values) <- variables$id 

    if(lang == "en"){ 
    test <- grepl(pattern="Tid", names(values)) 
    if(sum(test) > 0){ 
     values$Tid$id <- sub(pattern="Q", replacement="K", x=values$Tid$id) 
    } 
    } 

    ## Create basic_request for the data_post file 
    basic_request <- vector(mode="list", length=length(variables$id)) 
    for(variable in 1:length(variables$id)){ 

    var_name <- variables$id[variable] 

    if(var_name == "Tid"){ 
     basic_request[[variable]] <- list("code" = var_name, 
             "values" = as.character(values[[var_name]]$id[length(values[[var_name]]$id)])) 
    } else { 
     basic_request[[variable]] <- list("code" = var_name, 
             "values" = as.character(values[[var_name]]$id[1])) 
    } 
    } 
    return(list("basics" = basics, "variables" = variables, "values" = values, "basic_request" = basic_request)) 
} 

dst_get_data <- function(request, table,..., lang = "en", format = "CSV", value_presentation = "Default"){ 
    require(httr) 
    require(jsonlite) 

    dst_url <- "http://api.statbank.dk/v1/data" 

    final_request <- list("table" = table, 
         "lang" = lang, 
         "format" = format, 
         "valuePresentation" = value_presentation, 
         "variables" = request) 

    final_request <- jsonlite::toJSON(x=final_request, .escapeEscapes=TRUE, asIs=TRUE) 
    print(validate(final_request)) 
    data <- POST(url=dst_url, body=final_request, multipart=FALSE) 

    return(data) 
} 

test <- dst_meta(table="folk1") 

test2 <- dst_meta_parse(meta = test, lang = "en") 

test3 <- dst_get_data(request = test2$basic_request, table = "folk1", format="JSON") 
#test3 <- dst_get_data(request = test2$basic_request, table = "folk1", format="JSON") 
+0

이 코드를 패키지로 공개 할 계획이 있습니까? – Thomas

+0

@ 토마스 예, 저는 그것에 대해 생각해 보았습니다. 하지만 어제부터 시작 했으므로 현재의 형식이 아닙니다. 내 첫 번째 패키지이기 때문에 처음에는 github을 사용했습니다. (단지 소개 자료 중 일부를 따라 잡기 만하면됩니다.) – KERO

+0

차가움. 당신이 도움을 원한다면 알려주세요 (저는 Github에 계십니다). 나는 그런 패키지에 관심이있을 수 있다고 생각한다. – Thomas

답변

3

test3 <- dst_get_data(request = test2$basic_request, 
         table = "folk1", format="JSONSTAT") 

내가 얻을 :

Response [http://api.statbank.dk/v1/data] 
    Status: 200 
    Content-type: text/json 
{"dataset":{"dimension":{"Tid":{"label":"time","category":{"index":{"2014K2":0},"label":{"2014K2":"2014Q2"}}},"id":["Tid"],"size":[1],"role":{"time":["Tid"]}},"label":"Population at the first day of the quarter by time","source":"Statistics Denmark","updated":"2014-05-17T04:10:00Z","value":[5634437],"status":["a"]}} 

내가 그것을 모두 생각의 필요성 0 POST 당신을 위해 당신이 JSONSTAT 필요 automatically.The 이유를 JSON 변환을 할 것이라는 사실이 사용할 수있는 "형식은"당신이 (콘솔에서) 팝업에서 data을 선택하는 것이 사실에 기인는 다음과 같습니다

<select id="format" name="format"><option value="PX">PX</option> 
<option selected="selected" value="CSV">CSV</option> 
<option value="XLSX">XLSX</option> 
<option value="HTML">HTML</option> 
<option value="JSONSTAT">JSONSTAT</option> 
<option value="DSTML">DSTML</option> 
<option value="PNG">PNG</option> 
<option value="BULK">BULK</option> 
<option value="AREMOS">AREMOS</option> 
<option value="SDMXCOMPACT">SDMXCOMPACT</option> 
<option value="SDMXGENERIC">SDMXGENERIC</option> 
</select> 

일반 'JSON은 옵션 중 하나가 아닙니다.

+0

POST가 JSON과 작동하지 않는 이유가 궁금합니다! @hadley가 여기에서하고있는 것처럼 보입니다. [https://github.com/hadley/httr/blob/master/vignettes/api-packages.Rmd](https://github.com/hadley/httr/blob) /master/vignettes/api-packages.Rmd) 포인터에 감사드립니다! – KERO

+0

나는'JSONSTAT'에 대한 이유로 답을 갱신했다. JSON으로 자동 변환하는 것은 최근의 추가 일 수 있습니다 (따라서 Hadley의 예와 차이가 있음). – hrbrmstr

+0

편집 : 응답을 자세히 살펴 보지 않았기 때문에 주석을 삭제했습니다. – KERO