2013-10-09 41 views
1

我有一个由多个JSON对象组成的文件。我需要阅读这些文件并从JSON对象中提取某些字段。使事情复杂化,一些对象不包含所有的字段。我正在处理超过200,000个JSON对象的大文件。我想将作业分成多个核心。我曾试着用doSNOW,foreach和parallel进行实验,但实际上并不了解如何做到这一点。以下是我希望提高效率的代码。R中的并行编程

foreach (i in 2:length(linn)) %dopar% { 
    json_data <- fromJSON(linn[i]) 


    if(names(json_data)[1]=="info") 
    next 

    mLocation <- ifelse('location' %!in% names(json_data$actor),'NULL',json_data$actor$location$displayName) 
    mRetweetCount <- ifelse('retweetCount' %!in% names(json_data),0,json_data$retweetCount) 
    mGeo <- ifelse('geo' %!in% names(json_data),c(-0,-0),json_data$geo$coordinates) 

    tweet <- rbind(tweet, 
       data.frame(
       record.no  =  i, 
       id    =  json_data$id, 
       objecttype  =  json_data$actor$objectType, 
       postedtime  =  json_data$actor$postedTime, 
       location   =  mLocation, 
       displayname  =  json_data$generator$displayName, 
       link    =  json_data$generator$link, 
       body    =  json_data$body, 
       retweetcount  =  mRetweetCount, 
       geo    =  mGeo) 
       ) 

} 
+0

这时候你学会了在SO正确张贴代码块解析欺骗。 (另外'%!'不是一个标准的操作符......你应该包含所有依赖的包的名字,以使这段代码运行 –

回答

2

而不是试图并行迭代,我想你最好不要试图向量化(嗯,其实大部分的下面仍然是迭代...)。比如这里我们得到了我们所有的记录(无速度增益的是,虽然见下文......)

json_data <- lapply(linn, fromJSON) 

对于location我们预先分配的NA的向量来表示这是没有位置的记录,然后找到这记录有一个位置(也许有这样做的更好的方式...)和更新它们

mLocation <- rep(NA, length(json_data)) 
idx <- sapply(json_data, function(x) "location" %in% names(x$actor)) 
mLocation[idx] <- sapply(json_data[idx], function(x) x$location$displayName) 

最后,在一个单一的呼叫建立20万行数据帧(而不是你的“副本追加'模式,它会复制第一行,然后是第一行和第二行,然后是第一行,第二行,第三行en ...所以N平方的行,除了重新创建因素和其他data.frame特定的费用;你花大部分的时间)

data.frame(i=seq_along(json_data), location=mLocation) 

这个想法是积累的所有列,然后做一个呼叫data.frame()这是可能的。我想你可以在解析线在-A-时间,通过粘贴一切都变成一个字符串repersenting JSON数组,并在一个呼叫

json_data <- fromJSON(sprintf("[%s]", paste(linn, collapse=","))) 
+0

你的帖子让我想到了这一点,我创建了一个列和行的矩阵然后插入我需要它们的值,然后转换为数据帧。好多了,谢谢。 – Brandon