我试图从api
中删除一些json数据library(jsonlite)
pop_dat <- data.frame()
for (i in 1:3) {
# Generate url for each page
url <- paste0('http://api.worldbank.org/v2/countries/all/indicators/SP.POP.TOTL?format=json&page=',i)
# Get json data from each page and transform it into dataframe
dat <- as.data.frame(fromJSON(url)[2],flatten = TRUE, row.names = NULL)
pop_dat <- rbind(pop_dat, dat)
}
但是,它会返回以下错误:
row.names<-.data.frame
(*tmp*
,值=值)出错:
重复&#39; row.names&#39;不允许
另外:警告信息:
设置&#39; row.names&#39;:'1','10','11','12','13','14','15','16','时的非唯一值17','18','19','2','20','21','22','23','24','25','26','27','28' ,'29','3','30','31','32','33','34','35','36','37','38','39',' 4','40','41','42','43','44','45','46','47','48','49','5','50' ,'6','7','8','9'
将row.names更改为null并不起作用。我从某人那里听说,这是因为有些数据存储在这里,我不太明白。
我知道有一个替代软件包WDI来访问这些数据并且运行良好,但是我想知道如何在这里解决重复行名称问题,以便我可以处理类似的情况,其中没有替代软件包是可用。
答案 0 :(得分:1)
我从某人那里听说是因为某些数据存储为列表...
这是对的。解决方案相当简单,但我觉得这很容易被绊倒。现在你正在使用:
dat <- as.data.frame(fromJSON(url)[2],flatten = TRUE, row.names = NULL)
问题来自fromJSON(url)[2]
。这应该是fromJSON(url)[[2]]
。根据文档,[
和[[
之间的主要区别是单个括号可以选择多个元素,而[[
只选择一个。
你可以看到它如何与一些假数据一起使用。
foo <- list(
a = rnorm(100),
b = rnorm(100),
c = rnorm(100)
)
使用[
,您可以在此列表中选择多个值。
foo[c("a", "b")]
length(foo["a"]) # Result is 1 not 100 like you might expect.
[[
结果不同。
foo[[c("a", "b")]] # Raises a subscript error.
foo[["a"]] #This works.
length(foo[["a"]]) # Result is 100.
因此,您的答案将取决于您正在使用的子集运算符。对于您的问题,您需要使用[[
来选择列表中的单个data.frame。然后,您应该能够正确使用rbind。
final <- data.frame()
for (i in 1:10) {
url <- paste0(
'http://api.worldbank.org/v2/countries/all/indicators/SP.POP.TOTL?format=json&page=',
i
)
res <- jsonlite::fromJSON(url, flatten = TRUE)[[2]]
final <- rbind(final, res)
}
lapply的替代解决方案:
urls <- sprintf(
'http://api.worldbank.org/v2/countries/all/indicators/SP.POP.TOTL?format=json&page=%s',
1:10
)
resl <- lapply(urls, jsonlite::fromJSON, flatten = TRUE)
resl <- lapply(resl, "[[", 2) # Use lapply to select the 2 element from each list element.
resl <- do.call(rbind, resl) # This takes all the elements of the list and uses those elements as the arguments for rbind.