R: функция stream_out jsonlite, создающая неполный / усеченный файл JSON
Я пытаюсь загрузить действительно большой файл JSON в R. Поскольку файл слишком велик, чтобы поместиться в память на моем компьютере, я обнаружил, что с помощью jsonlite
пакет-х stream_in
/stream_out
функции действительно полезны. С помощью этих функций я могу сначала разбить данные на части без загрузки, записать данные подмножества в новый файл JSON меньшего размера, а затем загрузить этот файл как data.frame
, Однако этот промежуточный JSON-файл усекается (если это правильный термин), когда он записывается с stream_out
, Сейчас я попытаюсь объяснить более подробно.
Что я пытаюсь:
Я написал свой код следующим образом (следуя примеру из документации):
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))
Как вы видите, я открываю соединение с временным файлом, читаю мой оригинальный файл JSON с stream_in
и иметь handler
Функция подмножество каждого куска данных и записать его в соединение.
Эта проблема
Эта процедура выполняется без проблем, пока я не попытаюсь прочитать ее в myData <- stream_in(file(tmp))
, при котором я получаю ошибку. Открытие нового временного файла JSON вручную показывает, что самая нижняя строка всегда является неполной. Что-то вроде следующего:
{"Var1":"some data","Var2":3,"Var3":"some othe
Затем я должен вручную удалить эту последнюю строку, после чего файл загружается без проблем.
Решения, которые я пробовал
Я попытался внимательно прочитать документацию и посмотреть на
stream_out
функции, и я не могу понять, что может быть причиной этой проблемы. Единственное, что я имею в виду, это то, чтоstream_out
Функция автоматически закрывает соединение после завершения, так что, может быть, оно закрывает соединение, пока какой-то другой компонент все еще пишет?Я вставил функцию печати, чтобы напечатать
tail()
конецdata.frame
на каждом куске внутриhandler
функция для исключения проблем с посредникомdata.frame
,data.frame
производится безупречно на каждом интервале, и я вижу, что последние два или три рядаdata.frame
становятся усеченными во время записи в файл (т.е. они не записываются). Обратите внимание, что это самый конец всегоdata.frame
(послеstream_out
имеетrbind
все), который становится рубленым.Я пытался поиграть с
pagesize
аргументы, в том числе попытки очень больших чисел, без числа, иInf
, Ничего не сработало.Я не могу использовать
jsonlite
другие функции, такие какfromJSON
потому что исходный файл JSON слишком велик для чтения без потоковой передачи и фактически находится в минимизированном (?)/ndjson
формат.
Системная информация
Я использую R 3.3.3 x64 на Windows 7 x64. 6 ГБ оперативной памяти, AMD Athlon II с 4 ядрами, 2,6 ГГц.
лечение
Я все еще могу решить эту проблему, открыв вручную файлы JSON и исправив их, но это приводит к некоторой потере данных и не позволяет автоматизировать мой сценарий, что является неудобством, поскольку мне приходится многократно запускать его на протяжении всего проекта.
Я действительно ценю любую помощь с этим; благодарю вас.
1 ответ
Я считаю, что это делает то, что вы хотите, не нужно делать лишнее 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
колонка.)