2011-08-05 8 views
40

इसने वास्तव में आर कोड को डीबग करने की मेरी क्षमता को चुनौती दी है।ऑब्जेक्ट को किसी फ़ंक्शन के अंदर ddply के साथ त्रुटि नहीं मिली

मैं ddply() का उपयोग करना चाहता हूं ताकि समान कॉलम को क्रमशः नामित किया जा सके; जैसे। ए, बी, सी। ऐसा करने के लिए मैं बार-बार कॉलम नाम को एक स्ट्रिंग के रूप में पास करना चाहता हूं और फ़ंक्शन को संदर्भित करने की अनुमति देने के लिए eval(parse(text=ColName)) का उपयोग करना चाहता हूं। मैंने इस तकनीक को एक और जवाब से पकड़ लिया।

और यह तब तक अच्छा काम करता है जब तक कि मैं ddply() किसी अन्य फ़ंक्शन के अंदर नहीं डालता। यहां नमूना कोड है:

# Required packages: 
library(plyr) 

myFunction <- function(x, y){ 
    NewColName = "a" 
    z = ddply(x, y, summarize, 
      Ave = mean(eval(parse(text=NewColName)), na.rm=TRUE) 
    ) 
    return(z) 
} 

a = c(1,2,3,4) 
b = c(0,0,1,1) 
c = c(5,6,7,8) 
df = data.frame(a,b,c) 
sv = c("b") 

#This works. 
ColName = "a" 
ddply(df, sv, summarize, 
     Ave = mean(eval(parse(text=ColName)), na.rm=TRUE) 
) 

#This doesn't work 
#Produces error: "Error in parse(text = NewColName) : object 'NewColName' not found" 
myFunction(df,sv) 

#Output in both cases should be 
# b Ave 
#1 0 1.5 
#2 1 3.5 

कोई विचार? समारोह के अंदर भी NewColName परिभाषित किया गया है!

मैंने सोचा कि इस प्रश्न का उत्तर, loops-to-create-new-variables-in-ddply, मेरी मदद कर सकता है लेकिन मैंने आज के लिए पर्याप्त सिर टक्कर लगी है और अब मेरा हाथ उठाने और मदद मांगने का समय है।

उत्तर

14

जहां NewColName अभी भी दिखाई दे रहा है आप do.call और call के संयोजन के साथ ऐसा कर सकते हैं एक वातावरण में कॉल के निर्माण के लिए:

myFunction <- function(x,y){ 
NewColName <- "a" 
z <- do.call("ddply",list(x, y, summarize, Ave = call("mean",as.symbol(NewColName),na.rm=TRUE))) 
return(z) 
} 

myFunction(d.f,sv) 
    b Ave 
1 0 1.5 
2 1 3.5 
3

ऐसा लगता है कि आपके पास पर्यावरण समस्या है। ग्लोबल असाइनमेंट समस्या ठीक हो जाती है, लेकिन एक की आत्मा की कीमत पर:

library(plyr) 

a = c(1,2,3,4) 
b = c(0,0,1,1) 
c = c(5,6,7,8) 
d.f = data.frame(a,b,c) 
sv = c("b") 

ColName = "a" 
ddply(d.f, sv, summarize, 
     Ave = mean(eval(parse(text=ColName)), na.rm=TRUE) 
) 

myFunction <- function(x, y){ 
    NewColName <<- "a" 
    z = ddply(x, y, summarize, 
      Ave = mean(eval(parse(text=NewColName)), na.rm=TRUE) 
    ) 
    return(z) 
} 

myFunction(x=d.f,y=sv) 

eval parent.frame में लग रही है (1)। तो अगर आप के बजाय myfunction बाहर NewColName परिभाषित यह काम करना चाहिए:

rm(NewColName) 
NewColName <- "a" 
myFunction <- function(x, y){ 

    z = ddply(x, y, summarize, 
      Ave = mean(eval(parse(text=NewColName)), na.rm=TRUE) 
    ) 
    return(z) 
} 
myFunction(x=d.f,y=sv) 

get का उपयोग कर पहले पर्यावरण से my.parse बाहर खींच करके, हम बहुत करीब आ सकते हैं, लेकिन अभी भी है curenv एक वैश्विक रूप में पारित करने के लिए:

myFunction <- function(x, y){ 
    NewColName <- "a" 
    my.parse <- parse(text=NewColName) 
    print(my.parse) 
    curenv <<- environment() 
    print(curenv) 

    z = ddply(x, y, summarize, 
      Ave = mean(eval(get("my.parse" , envir=curenv)), na.rm=TRUE) 
    ) 
    return(z) 
} 

> myFunction(x=d.f,y=sv) 
expression(a) 
<environment: 0x0275a9b4> 
    b Ave 
1 0 1.5 
2 1 3.5 

मुझे लगता है कि पहले से ही ddply .GlobalEnv में मूल्यांकन कर रही है, जिसके कारण मैं parent.frame() और sys.frame() रणनीतियों के सभी में विफल रहा है की कोशिश की।

+0

मुझे संदेह है कि समाधान को @ हैडली फ़ंक्शन की आवश्यकता हो सकती है :-) –

+0

इन सभी को आजमाने में बहुत अच्छा प्रयास। ग्रुप हेड बैंगिंग की हमेशा सराहना की जाती है ...... मैं अपनी आत्मा –

9

मैं कभी कभी जब साथ summarize या transform या कुछ ddply संयोजन और, बहुत चालाक इन और विभिन्न वातावरण नेविगेट करने की बहिष्कार परमात्मा के लिए नहीं किया जा रहा मैं पक्ष-कदम बस summarize का उपयोग नहीं कर मुद्दे करते हैं इस तरह समस्याओं में चलाने के लिए और बजाय अपने ही अज्ञात फ़ंक्शन का उपयोग कर:

myFunction <- function(x, y){ 
    NewColName <- "a" 
    z <- ddply(x, y, .fun = function(xx,col){ 
          c(Ave = mean(xx[,col],na.rm=TRUE))}, 
       NewColName) 
    return(z) 
} 

myFunction(df,sv) 

जाहिर है, वहाँ 'मैन्युअल' इस सामग्री कर रही करने के लिए एक लागत है, लेकिन अक्सर यह मूल्यांकन के मुद्दों है कि ddply और summarize के संयोजन से आते हैं से निपटने का सिरदर्द बचा जाता है। यही कारण है कि निश्चित रूप से नहीं कहने के लिए है, यह है कि हेडली एक समाधान के साथ दिखाई नहीं देंगे ...

+2

रखूंगा जब तक कि मैं बग ठीक नहीं करता, यह मेरी अनुशंसित कामकाज है। ध्यान दें कि आप अपने अज्ञात फ़ंक्शन के अंदर 'ट्रांसफॉर्म' आदि का उपयोग कर सकते हैं। – hadley

+0

@ जोरान मैंने आपके समाधान को लागू किया और यह मेरे लिए काम किया। मैं सिर्फ इस बारे में जानबूझ कर रहा था कि डीडीपीई में इस स्कोपिंग मुद्दे क्यों है? क्या ऐसा इसलिए है क्योंकि संक्षेप में एक नया डेटाफ्रेम बनाता है और उसके पास इस कॉलनाम तक पहुंच नहीं है? –

+0

@ user3801801 इसे फ़ंक्शन तर्कों के गैर-मानक मूल्यांकन के साथ करना है। मुझे विशिष्ट मुद्दे के बारे में याद दिलाने के लिए स्रोत कोड के माध्यम से जाना होगा, लेकिन मूल रूप से यह करना है कि कैसे आर जानता है कि तर्क कहां मूल्यांकन करना है (यानी वर्तमान परिसर के संदर्भ में, वैश्विक पर्यावरण में, कहीं कहीं के बीच)। – joran

4

समस्या पीएलआर पैकेज के कोड में ही है। संक्षेप में समारोह में, eval(substitute(...),.data,parent.frame()) एक पंक्ति है। यह अच्छी तरह से जाना जाता है कि parent.frame() बहुत मजेदार और अप्रत्याशित सामान कर सकता है। टी

वह @ जेम्स का समाधान बहुत अच्छा कामकाज है, लेकिन अगर मुझे सही याद है तो हैडली ने खुद से पहले कहा था कि प्लीयर पैकेज का उपयोग कार्यों के भीतर नहीं किया जाना था।

क्षमा करें, मैं यहां गलत था। हालांकि यह ज्ञात है कि इस पल के लिए, प्लीयर पैकेज इन परिस्थितियों में समस्याएं देता है।

myFunction <- function(x, y){ 
    NewColName = "a" 
    z = aggregate(x[NewColName],x[y],mean,na.rm=TRUE) 
    return(z) 
} 
> myFunction(df,sv) 
    b a 
1 0 1.5 
2 1 3.5 
+0

+1 मेरा "सारांश 'सारांश" समाधान "लेने और समस्या का वास्तविक विवरण प्रदान करने के लिए। ;) – joran

+0

+1 निश्चित रूप से parent.frame() समस्या को समझाने के लिए समय निकालने के लिए +1। यह अजीब लगता है कि किसी फ़ंक्शन को किसी अन्य फ़ंक्शन के अंदर उपयोग नहीं किया जा सकता है क्योंकि यह आपको संगत कोड लिखने के लिए मजबूर करता है। शायद @ हैडली टिप्पणी कर सकता है। –

+0

मैंने निश्चित रूप से कभी दावा नहीं किया कि प्लीयर का उपयोग कार्यों के भीतर नहीं किया जाना था - मैंने हमेशा कहा है कि यह एक बग है जिसे वर्तमान में मुझे ठीक करने की समझ नहीं है :( – hadley

22

आज की इस प्रश्न का हल here(summarize) में summarize बनाना है:

इसलिए, मैं आप समस्या के लिए एक आधार समाधान दे। जैसे

myFunction <- function(x, y){ 
    NewColName = "a" 
    z = ddply(x, y, here(summarize), 
      Ave = mean(eval(parse(text=NewColName)), na.rm=TRUE) 
    ) 
    return(z) 
} 

here(f), plyr दिसम्बर 2012 में, वर्तमान संदर्भ कब्जा गयी।

+0

को सही बनाया गया है! लुब्रिडेट और प्लीयर का उपयोग करते समय, सुनिश्चित करें कि आप विशेष रूप से plyr :: here() (दुर्भाग्यवश यहां लुप्तप्राय रूप से परिभाषित करते हैं) के रूप में देखें। –

+0

अधिक जानकारी: https://github.com/hadley/plyr/ मुद्दों/3 – Lennert

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

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