2016-07-17 10 views
0

Census 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() 함수는 목록 객체를 만듭니다. 대부분의 경우, 목록 객체의 요소는 각 공간 단위 (예 : 위의 예에서는 county)의 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'패키지를 사용하고 싶지 않으므로 사용을 제안하지 마십시오. 나는이 문제를 다루는 방법을 배우려고 노력하고있다.

    simplify2array(l2) 
    

    편집 :

    위의 솔루션은 작동하지 않았다

+0

'as.data.frame (do.call (cbind, l2))'는 전형적 일 것입니다 (그러나 위대하지는 않지만, 타입을 잃을 것입니다). 'purrr'은리스트를 다루는데 유용합니다; 당신은'l2 %> setNames (make.names (seq_along (.)))> % at_depth (2, ~ .x % || % NA) %> % map_df (unlist)'같은 것을 할 수있다. 가장 우아한 버전은 아닙니다. – alistaire

답변

0

은 어쩌면 이것은 당신이 후에 무엇이다. 대안으로 나는 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) 
+0

실제 데이터에서는 작동하지 않는다고 생각합니다. 적어도 그것은 내 테스트에서 나왔다. (기형이 생겨서 한 차원을 없애고 3,222 열을 주었다.) 내가 틀렸다면 나를 바로 잡아라, OP. –

+0

@ Hack-R 슬프게도 실제 데이터가 없으므로 테스트 할 수 없습니다. 나는 OP가 제공 한 장난감 데이터를 작업 중이다 ... @ user3614648이 함수는 내부적으로'sapply()'에 사용되지 않는다. 그러나 우리는'simplify2array'라고 입력하여 코드를 검사 할 수 있습니다 - 당신이하는 일과 다소 비슷한 일을합니다 - 데이터를 제거한 다음 적절한 배열로 배열합니다. 각 하위 목록의 길이가 동일하기 때문에 귀하의 경우에 효과적입니다. 참조 :'길이 (l2)'(NULL이 있더라도). 길이가 다른 경우 작동하지 않을 수 있습니다. –

+0

@ user3614648 알겠습니다. 어쩌면 부정확 한 것에 대해 정교하게 설명하거나이 문제가 해결되지 않는 간단한 사례를 추가 할 수 있습니까? –

1

을 내가 네게 실제 쿼리를 사용하여 해킹 제공 :> 3,000에서 만

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) 길이가 비정상적 이었지만 구조 행을 원할 경우 누락 된 값을 자리 표시 자로 채우기 위해 다른 행을 추가하여 행을 구할 수 있습니다. 당신이 당신의 data.frame의 colnames에 쓸 수 있도록 마지막

는 첫 번째 행은 헤더 것을 잊지 마세요.

+0

이것은 목록의 문제가되는 요소를 식별하는 데 유용한 해킹입니다. 그것은 문제 자체에 대한 대답이 아니지만 도움이되기 때문에 나는 upvote 할 것입니다. 참고 : 개체가 반환 될 때 변수 이름이 첫 번째 행 (내 자신의 응용 프로그램에서 자동으로 수정 됨)에 나타나는 이유도 다소 수수께끼입니다. – user3614648