2017-09-05 126 views
0

我試圖在R中加載一個非常大的JSON文件。由於文件太大而無法放入我的機器的內存中,我發現使用jsonlite程序包的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文件顯示最底部的行總是不完整的。像下面這樣:

{"Var1":"some data","Var2":3,"Var3":"some othe 

我那麼必須手動刪除最後一行之後,文件加載沒有問題。

解決方案我已經試過

  1. 我試圖徹底閱讀文檔和看stream_out功能,我想不出什麼可能會造成這個問題。我唯一的線索是,stream_out函數在完成時自動關閉連接,所以也許它正在關閉連接,而其他組件仍在寫入?

  2. 我插入的打印功能打印data.frametail()結束在handler函數內每塊排除問題與中介data.framedata.frame是在每個時間間隔都完美地生成的,我可以看到data.frame的最後兩行或三行在寫入文件時被截斷(即它們沒有被寫入)。請注意,這是整個data.frame(在stream_outrbind編輯的所有東西之後)的最後部分。

  3. 我試着玩pagesize參數,包括嘗試非常大的數字,沒有數字和Inf。沒有任何工作。

  4. 因爲原來的JSON文件太大不流讀取,它實際上是在精縮(?)/ ndjson格式我不能使用jsonlite的其他功能,如fromJSON

系統信息

我在Windows 7 64位系統運行v 3.3.3 64位。 6 GB內存,AMD Athlon II 4核2.6 Ghz。

治療

我還是可以處理這個問題通過手動打開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條線,因此小的頁面大小,以檢查是否一切有超過一個大塊工作,因爲我是個懶人創造一個我使用的過濾器甚至標識。 Var列。)