我正在尝试使用 Census API 下载特定表格并将它们保存在数据框中。我已经成功下载了数据。我为调用组装了适当的 URL,然后使用包 'rjson' 将 URL 读入列表。例如:
library(rjson)
get <- c("B19081_002M") # create vector of vars
datafile <- "http://api.census.gov/data/2009/acs5?" # ACS 05-09
get <- paste0("get=NAME,", paste(get, collapse = ',')) # variables
geo <- "for=county:*" # all counties
api_key <- "key=KEYHERE" # API key
url <- paste0(datafile, paste(get, geo, api_key, sep = "&")) # creates url
data <- fromJSON(file = url) # read into R
# To see an example of a problematic observation
# (this should return "Hinsdale County, Colorado")
data[[273]]
但是,我很难将其转换为数据框。fromJSON() 函数创建一个列表对象。在大多数情况下,列表对象的元素是每个空间单元(例如上例中的县)的 chr 向量,并且该向量包含表信息和关联的元数据。在这种情况下,我使用以下工作示例中的方法将列表转换为数据框,其中每一行是不同的空间单位,每一列是不同的变量。
# Create fake data
x1 <- seq(1:5)
x2 <- rep(5,5)
l1 <- list(x1,x2)
# Convert to df
cols_per_row <- length(unlist(l1[1]))
test1 <- data.frame(matrix(unlist(l1), byrow = TRUE, ncol = cols_per_row))
print(test1) # success!
X1 X2 X3 X4 X5
1 1 2 3 4 5
2 5 5 5 5 5
但是,当我对 list-in-list 对象使用相同的方法时(这是因为我从 API 中包含了不同的表),我收到一个错误:
# Create fake data
x1 <- seq(1:5)
x2 <- rep(5,5)
x3 <- list(1,2,3,4,NULL)
l2 <- list(x1,x2,x3)
# Produces an error
cols_per_row <- length(unlist(l2[1]))
test2 <- data.frame(matrix(unlist(l2), byrow = TRUE, ncol = cols_per_row))
Warning message:
In matrix(unlist(l2), byrow = TRUE, ncol = cols_per_row) :
data length [14] is not a sub-multiple or multiple of the number of columns [5]
有人对此有解决方案吗?
- 我注意到子列表只出现在其中一个变量具有 NULL 值的情况下。
- 在主列表的元素也是列表的情况下,子列表的长度等于作为向量的主列表元素的向量的长度。
笔记
- 我不需要使用 fromJSON 并欢迎可能使这更容易的替代方案。
- 我不想使用“acs”包来完成这个,所以请不要建议使用它。我正在尝试学习如何处理这个问题。