2015-10-12 3 views
6

मैं समांतर में कई सूची आइटमों को संसाधित करने की कोशिश कर रहा हूं।"foreach" समांतर लूप रिटर्न <NA> s

मेरा लक्ष्य है: अपने मूल्यों के आधार पर प्रत्येक कॉलम पर कुछ लेबलिंग फ़ंक्शन चलाएं। फिर नोड नाम, कॉलम नाम, और संसाधित लेबल

के साथ डेटाफ्रेम वापस करें वर्कफ़्लो लूप के लिए सामान्य का उपयोग करके ठीक काम करता है। हालांकि, जब मैं फ़ोरैच लूप में एक ही चीज़ करने की कोशिश करता हूं, तो परिणाम (कृपया ध्यान दें: निम्नलिखित मूल डेटासेट का केवल एक अमूर्त है)

मुझे यकीन नहीं है कि वास्तव में क्या हो रहा है बीच .. यदि आप उस चीज़ को हल करने में मेरी मदद कर सकते हैं तो यह शानदार होगा :-)

set.seed(12345) 
options(stringsAsFactors = F) 


# I. Random data generation (Original data is in data frame format) 
random.data = list() 
random.data[["one"]] = as.data.frame(matrix(data = runif(n = 15), ncol = 3)) 
random.data[["two"]] = as.data.frame(matrix(data = runif(n = 15), ncol = 3)) 
random.data[["three"]] = as.data.frame(matrix(data = runif(n = 15), ncol = 3)) 



# II. Some function applied to each column to label/classify the values 
valslabel = function(DataCOlumn) { 
    if(mean(DataCOlumn) < 0.5) return("low") 
    return("high") 
} 



# III. Generating the desired output in a regular for loop : 

desiredOutput = list() 

for(frame.i in seq_along(random.data)) { 

    frame = random.data[[frame.i]] 
    frame.name = names(random.data)[frame.i] 
    frame.results = data.frame(frame.name = character(0), 
        mappedField = character(0), label = character(0)) 

    for(col.i in 1:ncol(frame)) { 
    frame.results[col.i, "frame.name"] = frame.name 
    frame.results[col.i, "mappedField"] = colnames(frame)[col.i] 
    frame.results[col.i, "label"] = valslabel(frame[,col.i]) 
    } 

    desiredOutput[[frame.name]] = frame.results 
} 


print(desiredOutput) 

# $one 
# frame.name mappedField label 
# 1  one   V1 high 
# 2  one   V2 high 
# 3  one   V3 low 
# 
# $two 
# frame.name mappedField label 
# 1  two   V1 low 
# 2  two   V2 high 
# 3  two   V3 low 
# 
# $three 
# frame.name mappedField label 
# 1  three   V1 low 
# 2  three   V2 high 
# 3  three   V3 high 




# IV. Using the "foreach" parallel execution 

library(foreach) 
library(doParallel) 

cl = makeCluster(6) 
registerDoParallel(cl) 

output = foreach(frame.i = seq_along(random.data), .verbose = T) %dopar% { 

    frame = random.data[[frame.i]] 
    frame.name = names(random.data)[frame.i] 
    frame.results = data.frame(frame.name = character(0), mappedField = character(0), label = character(0)) 

    for(col.i in 1:ncol(frame)) { 
    frame.results[col.i, "frame.name"] = frame.name 
    frame.results[col.i, "mappedField"] = colnames(frame)[col.i] 
    frame.results[col.i, "label"] = valslabel(frame[,col.i]) 
    } 

    return(frame.results) 
} 


print(output) 

# [[1]] 
# frame.name mappedField label 
# 1  <NA>  <NA> <NA> 
# 2  <NA>  <NA> <NA> 
# 3  <NA>  <NA> <NA> 
# 
# [[2]] 
# frame.name mappedField label 
# 1  <NA>  <NA> <NA> 
# 2  <NA>  <NA> <NA> 
# 3  <NA>  <NA> <NA> 
# 
# [[3]] 
# frame.name mappedField label 
# 1  <NA>  <NA> <NA> 
# 2  <NA>  <NA> <NA> 
# 3  <NA>  <NA> <NA> 

धन्यवाद!

उत्तर

3

समस्या तरह से आप अपने डेटा फ्रेम आरंभ, और तथ्य यह है कि foreach वातावरण में, विकल्प stringsAsFactorsFALSE पर सेट नहीं है से संबंधित है। क्या प्रत्येक foreach पाश में हो रहा है की तरह इस

options(stringsAsFactors = FALSE) 
d <- data.frame(x =character(0)) 
d[1, "x"] <- "a" 
#Warning message: 
#In `[<-.factor`(`*tmp*`, iseq, value = "a") : 
# invalid factor level, NA generated 
d 
#  x 
#1 <NA> 

नोट कुछ है कि यह केवल एक चेतावनी एक त्रुटि देता है, और नहीं तो पाश बंद नहीं होता है। आप सेट करते हैं stringsAsFactorsFALSE पहले करने के लिए वहाँ कोई समस्या नहीं है (जैसा कि आप था, जब नहीं समानांतर में सामान चल) अपने वैश्विक वातावरण में

options(stringsAsFactors = FALSE) 
d <- data.frame(x =character(0)) 
d[1, "x"] <- "a" 
d 
# x 
#1 a 

आप पहले से ही options(stringsAsFactors = FALSE) सेट तो %do% पाश काम किया। हालांकि यह विकल्प प्रत्येक समांतर नौकरी के स्थानीय वातावरण में पारित नहीं होता है और इसलिए %dopar% लूप ऊपर की समस्या में चलता है। निम्नलिखित

options(stringsAsFactors = FALSE) 
.Options$stringsAsFactors 
#[1] FALSE 
foreach(i = 1:3) %dopar% .Options$stringsAsFactors 
#[[1]] 
#[1] TRUE 
# 
#[[2]] 
#[1] TRUE 
# 
#[[3]] 
#[1] TRUE 

के उत्पादन में उदाहरण के लिए

देखो तो समाधान foreach पाश अंदर विकल्प stringsAsFactors = FALSE स्थापित करने के लिए है।

एक तरफ के रूप में, जब संभव हो तो पंक्ति-दर-पंक्ति के बजाय पूरे कॉलम वेक्टर का उपयोग करके अपना डेटा फ्रेम बनाना बेहतर होता है। अपने उदाहरण में आप

frame.results <- data.frame( 
    frame.name = frame.name, 
    mappedField = colnames(frame), 
    label = valslabel1(colMeans(frame))) 

जहां valslabel समारोह एक vectorised संस्करण

valslabel1 <- function(x) { 
    ifelse(x < 0.5, "low", "high") 
} 
+0

धन्यवाद Konvas ने ले लिया है साथ

frame.results = data.frame(frame.name = character(0), mappedField = character(0), label = character(0)) for(col.i in 1:ncol(frame)) { frame.results[col.i, "frame.name"] = frame.name frame.results[col.i, "mappedField"] = colnames(frame)[col.i] frame.results[col.i, "label"] = valslabel(frame[,col.i]) } 

बदल सकते हैं। बहुत अच्छी तरह पकड़ा !! –

+0

दिलचस्प ... इसे मेरे दिमाग में रखना है! – cryo111

+2

@Deena @ cryo111 जिस तरह से मैंने देखा कि यदि आप तर्क 'कोर' का उपयोग करके समांतर बैक एंड को पंजीकृत करते हैं, यानी 'रजिस्टर डूपरेल (कोर = 6)' विकल्प _is_ प्रत्येक नौकरी के स्थानीय वातावरण में पास किया गया है ... नहीं सुनिश्चित करें कि यह क्यों है और क्या यह प्लेटफॉर्म विशिष्ट – konvas

संबंधित मुद्दे