使用R从json文件构建数据帧时有效替代merge()?

Bry*_*yan 5 performance json r

我编写了以下代码,但是一旦我开始在数千条记录上执行它,它就会非常缓慢:

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)
Run Code Online (Sandbox Code Playgroud)

我试图从一系列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"))
Run Code Online (Sandbox Code Playgroud)

上面代码的最终结果是矩阵,其中列是出现在上面结构中的每个person属性,行是每个人的相关值.正如您所看到的,某些人缺少某些数据,因此我需要确保这些数据显示为NA并确保最终的内容位于正确的列中.此外,location它本身是一个具有两个组成部分的向量:state并且zip_code,意味着它需要被平展到可以与另一个人记录合并之前location.statelocation.zip_code之前; 这是我用unlist()的.然后我保持正在运行的主表people_data.

上面的代码有效,但您知道一种更有效的方法来完成我想要做的事情吗?它似乎merge()正在减慢这个速度......我有数百个文件,每个文件中有数百人.

谢谢!布赖恩

更新:基于下面的反馈,我尝试构建所有人的列表,然后将其全部转换为数据帧.我让它一夜之间运行,仍然没有完成数据帧.名单中约有50万人.该代码如下所示:

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)
Run Code Online (Sandbox Code Playgroud)

Dan*_*son 3

如果您不希望存在重复记录,则可以使用包rbind.fill中的记录plyr