2017-09-05 7 views
0

정말 큰 JSON 파일을 R에로드하려고합니다. 파일이 너무 커서 내 컴퓨터의 메모리에 맞지 않으므로 패키지의 stream_in/stream_out 기능이 정말 도움이됩니다. 이러한 함수를 사용하여 데이터를로드하지 않고 청크로 먼저 하위 집합으로 만들고 하위 세트의 새 JSON 파일에 하위 데이터를 작성한 다음 해당 파일을 data.frame으로로드 할 수 있습니다. 그러나이 중재 JSON 파일은 stream_out으로 쓰여지는 동안 잘리는 것으로 나타납니다 (올바른 용어 인 경우). 나는 이제 더 자세하게 설명하려고 시도 할 것이다. 당신이 볼 수 있듯이, 내가 임시에 대한 연결을 열R : jsonlite의 stream_out 함수로 불완전한/잘린 JSON 파일 생성

con_out <- file(tmp <- tempfile(), open = "wb") 
stream_in(file("C:/User/myFile.json"), handler = function(df){ 
     df <- df[which(df$Var > 0), ] 
     stream_out(df, con_out, pagesize = 1000) 
    }, pagesize = 5000) 
myData <- stream_in(file(tmp)) 

:

나는 이런 내 코드를 작성했습니다 (문서에서 다음 예제) : 내가 시도하고있어

파일, stream_in으로 내 원래 JSON 파일을 읽고 handler 기능을 각 데이터 청크의 하위 집합과 연결에 씁니다.

내가 어떤에 내가 오류가 발생, myData <- stream_in(file(tmp))에서 그것을 읽으려고 할 때까지

이 절차는 아무 문제없이 실행 문제. 새로운 임시 JSON 파일을 수동으로 열면 맨 아래 줄이 항상 불완전하다는 것을 알 수 있습니다. 다음과 같은 내용이 있습니다.

그런 다음 마지막 줄을 수동으로 제거해야만 파일이 문제없이로드됩니다.

솔루션 나는 철저하게 문서를 읽고 stream_out 기능을보고 시도했습니다

  1. 을 시도했습니다, 나는이 문제를 일으킬 수있는 무엇을 알아낼 수 없습니다. 내가 가진 유일한 단서는 stream_out 함수가 완료시 연결을 자동으로 닫음으로써 다른 컴포넌트가 아직 쓰고있는 동안 연결을 닫을 수 있다는 것입니다.

  2. 난 중간 data.frame 문제를 배제 할 handler 함수 내 모든 청크에 data.frametail() 단부를 인쇄하는 인쇄 기능을 삽입 하였다. data.frame은 매 간격마다 완벽하게 생성되며 data.frame의 마지막 2 ~ 3 행이 파일에 쓰여지는 동안 (즉, 쓰여지지 않고 있음) 잘 리게됩니다. 잘게 다가 가고있는 것은 data.frame (stream_out 다음에 rbind이있다)의 끝 부분입니다.

  3. 매우 큰 숫자, 번호 및 Inf을 시도하는 것을 포함하여 pagesize 인수를 가지고 놀아 보았습니다. 아무것도 효과가 없습니다. 원래 JSON 파일을 스트리밍없이 읽을 너무 커서가 축소 된 (?)/ndjson 형식으로 실제로 때문에

  4. 나는 fromJSON 같은 jsonlite의 다른 기능을 사용할 수 없습니다.

시스템 정보

나는 윈도우 7의 x64에 R에게 3.3.3 64을 실행하고 있습니다. 6GB RAM, AMD Athlon II 4 코어 2.6GHz.

치료

나는 아직도 수동으로 JSON 파일을 열고이를 수정하여이 문제를 처리 할 수 ​​있지만 불편로 인 자동화 할 수는 일부 데이터가 손실로 이어지는 그리고 그것은 내 스크립트를 허용하지 않는 것 나는 내 프로젝트를 반복해서 실행해야한다.

정말 고맙겠습니다. 고맙습니다.

+1

(~ 오프 주제이지만 ~ 관련). Apache Drill - drill.apache.org를 확인하십시오. 스트리밍 JSON (ndjson)을 잘 처리하며'sergeant' 패키지를 통해 dplyr을 사용할 수 있습니다. – hrbrmstr

+0

감사합니다, hrbrmstr! 나는 그것을 확인하고 내가 성공하면 다시보고 할 것이다. –

답변

0

나는 이것이 당신이 원하는대로한다고 믿는다. 추가로 stream_out/stream_in을 할 필요는 없다.

myData <- new.env() 
stream_in(file("MOCK_DATA.json"), handler = function(df){ 
    idx <- as.character(length(myData) + 1) 
    myData[[idx]] <- df[which(df$id %% 2 == 0), ] ## change back to your filter 
}, pagesize = 200) ## change back to 1000 
myData <- myData %>% as.list() %>% bind_rows() 

(나는 Mockaroo 일부 모의 데이터를 생성 : 생성 된 1000 선, 따라서 작은 페이지 크기를 확인하기 위해 모든 것을 하나 이상의 덩어리와 함께 일하면 나는를 만들 게으른 때문에 내가 사용하는 필터는 심지어 ID를했다. Var 칼럼)