我正在尝试使用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]
有人有解决方案吗?
备注
答案 0 :(得分:2)
我使用真实的查询给你一个黑客:
tmp <- data.frame(matrix(ncol=4))
for(i in 1:length(data)){
if(length(t(unlist(data[i]))) == 4){
tmp[i,] <- t(unlist(data[i]))
} else{
cat("Row number ", i, "has an abnormal length \n")
}
}
Row number 273 has an abnormal length Row number 550 has an abnormal length Row number 1900 has an abnormal length Row number 2733 has an abnormal length Row number 2737 has an abnormal length Row number 2753 has an abnormal length
head(tmp)
1 NAME B19081_002M state county 2 Aleutians East Borough, Alaska 8469 02 013 3 Aleutians West Census Area, Alaska 7691 02 016 4 Anchorage Municipality, Alaska 920 02 020 5 Bethel Census Area, Alaska 2414 02 050 6 Bristol Bay Borough, Alaska 9635 02 060
仅有6个&gt; 3,000有一个异常的长度,但是如果你想要救援这些行,可以通过添加另一行来填充缺失值并使用占位符。
最后,不要忘记第一行是标题,因此您可以将其写入data.frame的colnames
。
答案 1 :(得分:0)
也许这就是你所追求的:
simplify2array(l2)
编辑:
上述解决方案无效。作为替代方案,我会用NA替换NULL值:
# Function to replace NULL values to NA values inside a list
listNull2Na <- function(l) sapply(l, function(x) ifelse(is.null(x), NA, x))
# Substitute NULL values in your list and get matrix:
l2 <- sapply(l2, listNull2Na)