Почему я могу читать только один файл .json за раз? - PullRequest
0 голосов
/ 25 января 2019

У меня есть 500+ файлов .json, из которых я пытаюсь получить определенный элемент. Я не могу понять, почему я не могу читать больше, чем по одному за раз ..

Это работает:

library (jsonlite)
files<-list.files(‘~/JSON’)
file1<-fromJSON(readLines(‘~/JSON/file1.json),flatten=TRUE)
result<-as.data.frame(source=file1$element$subdata$data)

Однако, независимо от использования различных пакетов json (например, RJSONIO), я не могу применить это ко всему содержимому files. Я продолжаю получать ошибку ...

попытка запустить тот же код, что и функция, для всего содержимого списка файлов

for (i in files) { fromJSON(readLines(i),flatten = TRUE) as.data.frame(i)$element$subdata$data}

Моя цель - перебрать все 500+ и извлечь данные и их содержимое. В частности, если файл содержит элемент «subdata $ data», я хочу извлечь список и поместить их все в фрейм данных.

Примечание: файлы читаются как ASCII (ОС Windows). Это делает бот отрицательно влияет на одиночное извлечение, но для цикла я получаю «недопустимые байты символов»

Обновление 1/25/2019

Запустил следующее, но вернул ошибки ...

files<-list.files('~/JSON')
out<-lapply(files,function (fn) {
o<-fromJSON(file(i),flatten=TRUE)
as.data.frame(i)$element$subdata$data
})

Error in file(i): object 'i' not found

Также обновлена ​​ функция , на этот раз с ошибками UTF * ...

    files<-list.files('~/JSON')
out<-lapply(files,function (i,fn) {
o<-fromJSON(file(i),flatten=TRUE)
as.data.frame(i)$element$subdata$data
})

Error in parse_con(txt,bigint_as_char):
 lexical error: invalid bytes in UTF8 string. (right here)------^

Последнее обновление Думаю, я нашел решение сумасшедшей проблемы с байтами. Когда я запускаю readLines для файла .json, я могу применить из JSON),

e.x.

json<-readLines('~/JSON')
jsonread<-fromJSON(json)
jsondf<-as.data.frame(jsonread$element$subdata$data)
#returns a dataframe with the correct information

Проблема в том, что я не могу применить readLines ко всем файлам в папке JSON (PATH). Если я смогу помочь с этим, я думаю, что смогу бежать ...

files<-list.files('~/JSON')
for (i in files){
a<-readLines(i)
o<-fromJSON(file(a),flatten=TRUE)
as.data.frame(i)$element$subdata}

Необходимые шаги

применить readLines ко всем 500 файлам .json в папке JSON применить fromJSON к файлам из шага 1 создайте data.frame, который возвращает записи , если list (fromJSON) содержит $ element $ subdata $ data.

Мысли?

Решение (Обходной путь?)

К сожалению, fromJSON по-прежнему сталкивается с проблемами с файлами .json. Я предполагаю, что мой метод GET (httr) не может ждать / задерживать и загружать «симпатичную печать» и, таким образом, захватывает необработанный .json, который, в свою очередь, дает нечетные символы и в результате дает вездесущий '--- --- ^ 'ошибка. Тем не менее, мне удалось составить решение, см. Ниже. Я хочу опубликовать его для будущих пользователей, у которых может быть такая же проблема с файлами .json, которые не работают ни с одним пакетом R json.

#keeping the same 'files' variable as earlier
raw_data<-lapply(files,readLines)
dat<-do.call(rbind,raw_data)
dat2<-as.data.frame(dat,stringsasFactors=FALSE)
#check to see json contents were read-in
dat2[1,1]

library(tidyr)
dat3<-separate_rows(dat2,sep='')
x<-unlist(raw_data)
x<-gsub('[[:punct:]]', ' ',x)

#Identify elements wanted in original .json and apply regex
y<-regmatches(x,regexc('.*SubElement2 *(.*?) *Text.*',x))

1 Ответ

0 голосов
/ 25 января 2019
  1. for циклы никогда ничего не возвращают, поэтому вы должны сохранить все ценные данные самостоятельно.
  2. Вы вызываете as.data.frame(i), который создает фрейм с ровно одним элементом, именем файла, вероятно, не то, чтоВы хотите сохранить.
  3. (Незначительно) Используйте fromJSON(file(i),...).
  4. Поскольку вы хотите захватить их в один кадр, я предлагаю что-то вроде:

    out <- lapply(files, function(fn) {
      o <- fromJSON(file(fn), flatten = TRUE)
      as.data.frame(o)$element$subdata$data
    })
    allout <- do.call(rbind.data.frame, out)
    ### alternatives:
    allout <- dplyr::bind_rows(out)
    allout <- data.table::rbindlist(out)
    
...