पहले, मैं नोट करना चाहिए कि त्रुटि दूर हो जाता है तो एक-दूसरे चर के नाम का base
में नहीं किया जाता है का उपयोग करता है - उदाहरण के लिए, अगर हम factor
के बजाय a
का उपयोग करें। यह स्पष्ट रूप से इंगित करता है कि llply
base::factor
(एक फ़ंक्शन) factor
(मान 1 के साथ परिवर्तनीय) से पहले अपने खोज पथ के साथ पाता है। मैं, llply
का एक सरलीकृत संस्करण है, अर्थात के साथ इस मुद्दे को दोहराने की कोशिश की है
library(plyr)
library(foreach)
library(doParallel)
workers <- makeCluster(2)
registerDoParallel(workers,cores=2)
factor=1
llply_simple=function(.x,.fun,.paropts) {
#give current environment a name
tmpEnv=environment()
attr(tmpEnv,"name")="llply_simple_body"
#print all enclosing envirs of llply_simple_body (see def of allEnv below)
print(allEnv(tmpEnv))
cat("------\nResults:\n")
do.ply=function(i) {
.fun(i)
}
fe_call <- as.call(c(list(quote(foreach::foreach), i = .x), .paropts))
fe <- eval(fe_call)
foreach::`%dopar%`(fe, do.ply(i))
}
llply_simple
एक पुनरावर्ती सहायक समारोह (allEnv
) है कि सभी संलग्न वातावरण के माध्यम से लूप का उपयोग करता है। यह सब पर्यावरण नाम के साथ एक वेक्टर रिटर्न
allEnv=function(x) {
if (environmentName(x)=="R_EmptyEnv") {
return(environmentName(x))
} else {
c(environmentName(x),allEnv(parent.env(x)))
}
}
यह दिलचस्प सरलीकृत समारोह वास्तव में काम करता है के रूप में उम्मीद
llply_simple(1:2,function(x) x*factor,list(.export="factor"))
#[1] "llply_simple_body" "R_GlobalEnv" "package:doParallel" "package:parallel"
#[5] "package:iterators" "package:foreach" "package:plyr" "tools:rstudio"
#[9] "package:stats" "package:graphics" "package:grDevices" "package:utils"
#[13] "package:datasets" "package:methods" "Autoloads" "base"
#[17] "R_EmptyEnv"
#--------
#Results:
#[[1]]
#[1] 1
#
#[[2]]
#[1] 2
(यानी, 1
और परिणाम के रूप में 2
देता है) कि तो साथ llply_simple
का केवल महत्वपूर्ण अंतर पूर्ण plyr::llply
फ़ंक्शन का सम्मान यह है कि उत्तरार्द्ध एक पैकेज से संबंधित है। आइए पैकेज में llply_simple
स्थानांतरित करने का प्रयास करें।
package.skeleton(list=c("llply_simple","allEnv"),name="llplyTest")
unlink("./llplyTest/DESCRIPTION")
devtools::create_description("./llplyTest",
extra=list("devtools.desc.author"='"T <[email protected]>"'))
tmp=readLines("./llplyTest/man/llply_simple.Rd")
tmp[which(grepl("\\\\title",tmp))+1]="Test1"
writeLines(tmp,"./llplyTest/man/llply_simple.Rd")
tmp=readLines("./llplyTest/man/allEnv.Rd")
tmp[which(grepl("\\\\title",tmp))+1]="Test2"
writeLines(tmp,"./llplyTest/man/allEnv.Rd")
devtools::install("./llplyTest")
और अब हमारे नए पैकेज से llplyTest::llply_simple
निष्पादित करने के लिए llplyTest
library(llplyTest)
llplyTest::llply_simple(1:2,function(x) x*factor,list(.export="factor"))
#[1] "llply_simple_body" "llplyTest" "imports:llplyTest" "base"
#[5] "R_GlobalEnv" "package:doParallel" "package:parallel" "package:iterators"
#[9] "package:foreach" "package:plyr" "tools:rstudio" "package:stats"
#[13] "package:graphics" "package:grDevices" "package:utils" "package:datasets"
#[17] "package:methods" "Autoloads" "base" "R_EmptyEnv"
#------
#Results:
#Error in do.ply(i) :
# task 1 failed - "non-numeric argument to binary operator"
अचानक हम 2013 से अपने मूल प्रश्न में के रूप में ही त्रुटि मिलती है सब के सब तो इस मुद्दे को स्पष्ट रूप से बुला से जुड़ा है कोशिश एक पैकेज से समारोह। आइए allEnv
के आउटपुट पर नज़र डालें: यह मूल रूप से उन वातावरणों का अनुक्रम देता है जो llpy_simple
और llplyTest::llpy_simple
निर्यात किए जाने वाले चरों को देखने के लिए उपयोग करते हैं। वास्तव में यह foreach
कि निर्यात करता है और एक करता है, तो क्यों foreach
वास्तव में पर्यावरण कि हम llply_simple_body
नामित साथ शुरू होता है, foreach::%dopar%
, foreach:::getDoPar
और foreach:::.foreachGlobals$fun
के स्रोत कोड को देखो और envir
तर्क के मार्ग का अनुसरण करने के लिए दिलचस्पी है।
अब हम स्पष्ट रूप से देख सकते हैं कि गैर-पैकेज संस्करण में llplyTest::llpy_simple
से भिन्न खोज अनुक्रम है और पैकेज-संस्करण base
में factor
मिलेगा!
आपके इनपुट के लिए धन्यवाद। यहां समस्या मूल्यांकन के पर्यावरण का इतना अधिक नहीं है, लेकिन निर्यात किए जाने वाले चर खोजने के लिए पर्यावरण 'foreach' किस प्रकार उपयोग करता है। समस्या दूर हो जाती है यदि कोई एक वैरिएबल नाम का उपयोग करता है जिसका उपयोग 'आधार' में नहीं किया जाता है, तो 'कारक' के बजाय 'a' कहें। मुझे पता है कि मैं सीधे 'foreach' का उपयोग कर सकता हूं (जैसे आपने किया और मैं आजकल ज्यादातर करता हूं) और यह कि त्रुटि तब खत्म हो जाती है। लेकिन 2013 में वापस मैं एक भारी 'प्लीयर' उपयोगकर्ता था और इस त्रुटि ने मुझे काफी परेशान किया। तो, मैं जिज्ञासा से इसे हल करना चाहता था। – cryo111