2013-10-09 76 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