Я написал следующий код, который работает, но мучительно медленно, как только я запускаю его для тысяч записей:
require("RJSONIO")
people_data <- data.frame(person_id=numeric(0))
json_data <- fromJSON(json_file)
n_people <- length(json_data)
for(person in 1:n_people) {
person_dataframe <- as.data.frame(t(unlist(json_data[[person]])))
people_data <- merge(people_data, person_dataframe, all=TRUE)
}
output_file <- paste("people_data",".csv")
write.csv(people_data, file=output_file)
Я пытаюсь создать единую таблицу данных из серии json-форматированных файлов. Функция fromJSON()
считывает данные как списки списков. Каждый элемент списка - это человек, который затем содержит список атрибутов для этого человека.
Например:
[[1]]
person_id
name
gender
hair_color
[[2]]
person_id
name
location
gender
height
[[...]]
structure(list(person_id = "Amy123", name = "Amy", gender = "F",
hair_color = "brown"),
.Names = c("person_id", "name", "gender", "hair_color"))
structure(list(person_id = "matt53", name = "Matt",
location = structure(c(47231, "IN"),
.Names = c("zip_code", "state")),
gender = "M", height = 172),
.Names = c("person_id", "name", "location", "gender", "height"))
Конечным результатом приведенного выше кода является матрица, где столбцы - это каждый атрибут человека, который появляется в приведенной выше структуре, а строки - соответствующие значения для каждого человека. Однако, как вы можете видеть, некоторые данные отсутствуют для некоторых людей, поэтому мне нужно убедиться, что они отображаются как NA
, и убедиться, что все заканчивается в правильных столбцах. Кроме того, location
сам по себе является вектором с двумя компонентами: state
и zip_code
, что означает, что он должен быть сведен к location.state
и location.zip_code
, прежде чем он может быть объединен с записью другого человека; это то, что я использую unlist()
для. Затем я сохраняю таблицу рабочего мастера в people_data
.
Приведенный выше код работает, но знаете ли вы о более эффективном способе выполнить то, что я пытаюсь сделать? Похоже, merge()
замедляет это для сканирования ... У меня есть сотни файлов с сотнями людей в каждом файле.
Спасибо!
Bryan
UPDATE:
Основываясь на отзывах, приведенных ниже, я попытался составить список всех людей, а затем преобразовать все это за один раз в массив данных. Я позволил этому работать быстро и все еще не закончил создание кадра данных. В списке около 1/2 миллиона человек. Эти коды выглядят так:
require("RJSONIO")
require("plyr")
people_data <- data.frame(person_id=numeric(0))
people_list <- list()
json_data <- fromJSON(json_file)
n_people <- length(json_data)
for(person in 1:n_people) {
people_list[[person]] <- t(unlist(json_data[[person]]))
}
#PROBLEM CODE, SLOW, 1/2 million records in people_list
people_data <- rbind.fill(lapply(people_list, as.data.frame))
output_file <- paste("people_data",".csv")
write.csv(people_data, file=output_file)