【发布时间】:2019-08-06 12:13:42
【问题描述】:
我正在从联合国的 SDG 指标 API 下载嵌套的 json 数据,但是使用 50,006 个分页的循环太慢了,无法完成。有没有更好的办法?
https://unstats.un.org/SDGAPI/swagger/#!/Indicator/V1SdgIndicatorDataGet
我正在使用 Windows 笔记本电脑上的 RStudio 工作。获取 json 嵌套数据并将其结构化为数据框是一场艰苦的胜利,但处理分页让我很难过。联合国统计电子邮件没有回复。 也许“申请”会做到这一点?我只需要 2004 年、2007 年和 2011 年的数据——也许我可以过滤,但我认为这对根本问题没有帮助。
我可能误解了 API 结构 - 我看不出单独查询 50,006 个页面如何对任何人都有效。感谢您的任何见解!
library(dplyr)
library(httr)
library(jsonlite)
#Get data from the first page, and initialize dataframe and data types
page1 <- fromJSON("https://unstats.un.org/SDGAPI/v1/sdg/Indicator/Data", flatten = TRUE)
#Get number of pages from the field of the first page
pages <- page1$totalPages
SDGdata<- data.frame()
for(j in 1:25){
SDGdatarow <- rbind(page1$data[j,1:16])
SDGdata <- rbind(SDGdata,SDGdatarow)
}
SDGdata[1] <- as.character(SDGdata[[1]])
SDGdata[2] <- as.character(SDGdata[[2]])
SDGdata[3] <- as.character(SDGdata[[3]])
#Loop through all the rest of the pages
baseurl <- ("https://unstats.un.org/SDGAPI/v1/sdg/Indicator/Data")
for(i in 2:pages){
mydata <- fromJSON(paste0(baseurl, "?page=", i), flatten=TRUE)
message("Retrieving page ", i)
for(j in 1:25){
SDGdatarow <- rbind(mydata$data[j,1:16])
rownames(SDGdatarow) <- as.numeric((i-1)*25+j)
SDGdata <- rbind.data.frame(SDGdata,SDGdatarow)
}
}
我确实得到了我想要的数据,并且在一个不错的数据框中,但是在几百页之后,查询不可避免地会出现连接问题,或者我的笔记本电脑关闭等。每页大约需要 5 秒。 5*50,006/3600 ~= 70 小时。
【问题讨论】:
-
一些事情。用
*apply或其他东西替换循环。不知道为什么要这样做两次?SDGdatarow <- rbind(mydata$data[j,1:16])。为什么不对所有页面执行一次? -
谢谢。首先获取第一页有助于设置我认为的数据框和类型,有助于索引,并且不需要任何实时。我曾尝试使用“应用”,但我并不擅长,并且不知道如何让它发挥作用(目前)。
-
API 文档中一定遗漏了一些东西。这似乎(在我看来)在计算上不值得。
-
我想我想通了:我可以设置每页的元素数量,从而可以控制可管理的页面数量。我还过滤了我想要的 3 年,这减少了数据。通过实验,我发现大约 1/10 的元素可以下载,所以我将调用设置为每页 1/10,循环 10 页。大约需要 20 分钟,但比 70 小时要好,并且可以在不丢失连接的情况下工作。