2011-08-09 6 views
11

मैं अभिव्यक्ति का उपयोग तर्क के रूप में करने के लिए एक एस 4 विधि को मनाने की कोशिश कर रहा हूं, लेकिन मुझे हमेशा एक त्रुटि लौटा दी जाती है। एक तुच्छ उदाहरण है कि एक सा है कि मैं क्या यहाँ करने के लिए कोशिश कर रहा हूँ दिखाता है:अभिव्यक्ति के साथ एस 4 विधियों को प्रेषण के रूप में प्रेषण

setGeneric('myfun',function(x,y)standardGeneric('myfun')) 

setMethod('myfun',c('data.frame','expression'), 
      function(x,y) transform(x,y)) 

अगर मैं अब कोशिश:

> myfun(iris,NewVar=Petal.Width*Petal.Length) 
Error in myfun(iris, NewVar = Petal.Width * Petal.Length) : 
    unused argument(s) (NewVar = Petal.Width * Petal.Length) 

> myfun(iris,{NewVar=Petal.Width*Petal.Length}) 
Error in myfun(iris, list(NewVar = Petal.Width * Petal.Length)) : 
error in evaluating the argument 'y' in selecting a method for 
function 'myfun': Error: object 'Petal.Width' not found 

ऐसा लगता है तर्क सामान्य में मूल्यांकन किया जाता पहले से ही अगर मैं यह सही समझ में । तो तरीकों से नीचे अभिव्यक्ति गुजरना कम से कम मुश्किल लगता है। अभिव्यक्तियों का उपयोग कर एस 4 प्रेषण विधियों का उपयोग करने की संभावना है?


संपादित करें: परिवर्तित करने के लिए बदल दिया गया है, क्योंकि यह एक बेहतर उदाहरण है।

+1

एसएफडीए के पीजी 39 9-402 देखें जहां चैंबर बताते हैं कि किसी भी हस्ताक्षर-परीक्षण तर्क _must_ का मूल्यांकन क्यों किया जाए। –

+0

@DWin: एक लिंक साझा करने की देखभाल? एसएफडीए मुझे अपरिचित लगता है, और मुझे लगता है कि आप राज्य खाद्य और औषधि प्रशासन के बारे में बात नहीं कर रहे हैं ... –

+0

क्षमा करें। जॉन चेम्बर्स द्वारा "डेटा विश्लेषण के लिए सॉफ्टवेयर"। एक अतिरिक्त बिंदु के रूप में मैंने देखा कि आपके हस्ताक्षर मूल्य तर्क नामों से जुड़े नहीं थे, जबकि प्रारूप में उदाहरण हैं। (ध्यान दें: आपने अभी तक प्रश्न निकाय में 'ट्रांसफॉर्म' में नहीं बदला है।) –

उत्तर

2

आपने इस उदाहरण विधि में दूसरे तर्क के वर्ग के रूप में "अभिव्यक्ति" निर्दिष्ट की है। पहला उदाहरण, एक त्रुटि देता है क्योंकि

NewVar=Petal.Width*Petal.Length 

मूल्य

Petal.Width*Petal.Length 

कि मौका नहीं मिलता है मूल्यांकन किया जाना साथ पीछे करने के लिए एक नामित तर्क के रूप में व्याख्या की जा रही है क्योंकि NewVar कोई तर्क नहीं है इस विधि या सामान्य के लिए।

दूसरे उदाहरण में, मुझे यकीन है कि क्या बंद घुंघराले ब्रेसिज़ के साथ चल रहा है नहीं कर रहा हूँ के रूप में मेरी त्रुटि से पता चला एक से अलग है: मूल्यांकन करने में त्रुटि: पीछे में

त्रुटि (आईरिस, { फंक्शन 'myfun' के लिए एक विधि का चयन करने में तर्क 'y': त्रुटि: ऑब्जेक्ट 'Petal.Width' नहीं मिला

हालांकि, मुझे कोई त्रुटि नहीं मिलती है और आईरिस डेटा प्राप्त होता है जब मैं आपकी अभिव्यक्ति को मजबूर करता हूं एक अभिव्यक्ति वस्तु:

myfun(iris, expression(NewVar=Petal.Width*Petal.Length)) 

मुझे लगता है कि यह केवल आंशिक रूप से आपके प्रश्न का उत्तर देता है, क्योंकि आईरिस डेटा को लौटाने से पहले। फ्रेम वह नहीं था जो आप चाहते थे। अभिव्यक्ति का मूल्यांकन() द्वारा उचित रूप से मूल्यांकन नहीं किया जा रहा है। मुझे लगता है आप आउटपुट निम्नलिखित हार्ड-कोडेड संस्करण से वास्तव में उत्पादन का मिलान करना चाहते:

transform(iris, NewVar=Petal.Width*Petal.Length) 

यहाँ एक छोटी उदाहरण eval का उपयोग कर अभिव्यक्ति का मूल्यांकन है

z <- expression(NewVar = Petal.Width*Petal.Length) 
test <- eval(z, iris) 
head(test, 2) 

[1] 0.28 0.28

यहां एक संस्करण है जो डेटा पर एक चर कॉलम जोड़ने के लिए काम करता है।फ्रेम:

setGeneric('myfun',function(x,y)standardGeneric('myfun')) 
setMethod('myfun',c('data.frame','expression'), function(x,y){ 
    etext <- paste("transform(x, ", names(y), "=", as.character(y), ")", sep="") 
    eval(parse(text=etext)) 
}) 
## now try it. 
test <- myfun(iris, expression(NewVar=Petal.Width*Petal.Length)) 
names(test) 

[1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "प्रजाति" "NewVar"

head(test) 

    Sepal.Length Sepal.Width Petal.Length Petal.Width Species NewVar 
1   5.1   3.5   1.4   0.2 setosa 0.28 
2   4.9   3.0   1.4   0.2 setosa 0.28 

फिर, यह कार्यान्वयन है अनिवार्य रूप से हार्ड कोडित किया गया है कि एक, और केवल एक, परिवर्तनीय कॉलम इनपुट डेटा.फ्रेम में जोड़ा जाएगा, हालांकि उस चर कॉलम का नाम और अभिव्यक्ति मनमानी है, और अभिव्यक्ति के रूप में प्रदान की जाती है। मुझे यकीन है कि एक बेहतर, अधिक सामान्य उत्तर है जो वाई में आयोजित अभिव्यक्ति का मूल्यांकन करेगा जैसे कि यह ट्रांसफॉर्म() फ़ंक्शन में प्रत्यक्ष कॉल था, लेकिन मैं इस समय फंस गया हूं कि उपयुक्त "उलटा" "अभिव्यक्ति के लिए समारोह()।

वहाँ हमेशा मानक है ..., यदि आप नहीं करते हैं वास्तव में y पर प्रेषण करने के लिए करना चाहते हैं:

setGeneric('myfun', function(x, ...) standardGeneric('myfun')) 
setMethod('myfun', 'data.frame', function(x, ...){ 
    transform(x, ...) 
}) 

और यह महान काम करता है। लेकिन आपका प्रश्न वास्तव में एक अभिव्यक्ति वस्तु पर प्रेषण के बारे में था।

निम्नलिखित काम नहीं करता है, लेकिन मुझे लगता है कि यह करीब हो रहा है। शायद किसी में कूद और कुछ अंतिम तोड़ मरोड़ कर सकते हैं:

setGeneric('myfun', function(x, y) standardGeneric('myfun')) 
setMethod('myfun',c('data.frame', 'expression'), function(x, y){ 
    transform(x, eval(y, x, parent.frame())) 
}) 
## try out the new method 
z <- expression(NewVar = Petal.Width*Petal.Length) 
test <- myfun(iris, z) 
names(test) 

[1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "प्रजाति"

अनिवार्य रूप से, अभिव्यक्ति का "नयाव =" टुकड़ा ट्रांसफॉर्म() को पारित नहीं किया गया था जब हमने myfun() को बुलाया था।

अधिक परीक्षण और त्रुटि के बाद, मैंने एक ऐसा तरीका निकाला जो वास्तविक के लिए काम करता है। सबसे पहले as.list() के साथ एक सूची में अभिव्यक्ति वस्तु कनवर्ट करते हैं, तो कॉल है कि आप अद्भुत

do.call() 

पूर्ण उदाहरण के साथ चाहते हैं का निर्माण इस तरह दिखता है:

setGeneric('myfun', function(x, y) standardGeneric('myfun')) 
setMethod('myfun',c('data.frame', 'expression'), function(x, y){ 
    do.call("transform", c(list(x), as.list(y))) 
}) 
# try out the new method 
z <- expression(NewVar = Petal.Width*Petal.Length) 
test <- myfun(iris, z) 
names(test) 
[1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species"  
[6] "NewVar" 

और नई data.frame ऑब्जेक्ट "टेस्ट" में "न्यूवायर" कॉलम है जो हम चाहते थे।

+1

जब आपके पास नेस्टेड फ़ंक्शंस होते हैं तो eval समस्याओं का एक नया सेट सेट करता है। वातावरण ... मुझे पता है कि मैं इसे हार्डकोड कर सकता हूं, लेकिन बिंदु अनिवार्य रूप से बदलने की लचीलापन है लेकिन मेरे स्वयं के एस 4 ऑब्जेक्ट्स के लिए है। मैंने इसे एस 3 विधियों का उपयोग करके हल किया, लेकिन मुझे विशेष रूप से दिलचस्पी थी कि स्क्रीन के पीछे क्या चल रहा था ... –

+1

हां, मुझे eval के साथ एक ही समस्या मिल रही थी। मुझे लगता है कि मैंने जो डॉट.call दृष्टिकोण जोड़ा है वह आपकी समस्या के लिए काम कर सकता है। –

+1

सबसे अच्छा कामकाज मैं पा सकता था, तो आप वहां जाते हैं। –

1

यह एस 4, या तर्क मूल्यांकन नहीं है, यह आर नहीं बता सकता है कि क्या आप नामित पैरामीटर पास करना चाहते हैं या यदि आपकी अभिव्यक्ति फॉर्म = b है।

यदि आप "भीतर" के लिए सहायता देखते हैं, तो यह अभिव्यक्ति के रूप में अभिव्यक्ति को पारदर्शी बनाने के लिए घुंघराले ब्रैकेट का उपयोग करता है।

मैं भी भीतर के अंदर एक समारोह समारोह की कॉलर में प्रतिस्थापन काम नहीं चलेगा बुला ...

मैं भी लगता है कि मैं भाव के बारे में पर्याप्त जानकारी नहीं है लगता है।

+0

केवल ब्रेसिज़ नहीं हैं क्योंकि 'एक्सप्रप्र' एकाधिक अभिव्यक्तियों के अर्थ में एक बहु-रेखा अभिव्यक्ति है? यदि आप एकल आर अभिव्यक्ति की आपूर्ति करते हैं तो आपको 'भीतर()' में ब्रेसिज़ की आवश्यकता नहीं है। –

+0

नामित पैरामीटर या अभिव्यक्ति के बारे में आपका बिंदु दिलचस्प है। क्या यह ऐसा समय है जहां '=' और '<-' की असमानता असाइनमेंट के रूप में @ जॉरीस को गधे में काट रही है? आईआईआरसी आपको '(-' 'में' <-' 'का उपयोग करना चाहिए, क्योंकि' = 'असाइनमेंट के रूप में काम नहीं करता है। –

+0

इसे आज़माएं: यह काम नहीं करता है। '<-' का उपयोग करने के लिए वही। –

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