Я пытаюсь использовать API переписи для загрузки определенных таблиц и сохранения их в кадрах данных. Мне удалось загрузить данные. Я собираю соответствующий URL для вызова, а затем использовал пакет «rjson» для чтения URL-адреса в списке. Например:R: Преобразование списка списков в фрейм данных (данные переписи)
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
Но когда я использую тот же подход с прейскурантной-в-списке объекта (который возникает потому, что я в том числе различных таблиц из 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» для этого, поэтому, пожалуйста, не предлагайте его использовать. Я пытаюсь научиться справляться с этой проблемой.
'as.data.frame (do.call (cbind, l2)) 'будет типичным (но не большим, вы потеряете типы) способом. 'purrr' полезен для работы со списками; вы можете сделать что-то вроде 'l2%>% setNames (make.names (seq_along (.)))%>% at_depth (2, ~ .x% ||% NA)%>% map_df (unlist)', хотя это может не самая изящная версия. – alistaire