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

Затем я должен вручную удалить эту последнюю строку, после чего файл загружается без проблем.

Решения, которые я пробовал

  1. Я попытался внимательно прочитать документацию и посмотреть на stream_out функции, и я не могу понять, что может быть причиной этой проблемы. Единственное, что я имею в виду, это то, что stream_out Функция автоматически закрывает соединение после завершения, так что, может быть, оно закрывает соединение, пока какой-то другой компонент все еще пишет?

  2. Я вставил функцию печати, чтобы напечатать tail() конец data.frame на каждом куске внутри handler функция для исключения проблем с посредником data.frame, data.frame производится безупречно на каждом интервале, и я вижу, что последние два или три ряда data.frame становятся усеченными во время записи в файл (т.е. они не записываются). Обратите внимание, что это самый конец всего data.frame (после stream_out имеет rbindвсе), который становится рубленым.

  3. Я пытался поиграть с pagesize аргументы, в том числе попытки очень больших чисел, без числа, и Inf, Ничего не сработало.

  4. Я не могу использовать 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 колонка.)

Другие вопросы по тегам