2014-09-23 9 views
5

मेरे neverending खोज चीजों को तोड़ने के लिए में, पर विचार करें:जांच करने का तरीका संशोधित समारोह औपचारिक

gbar<-function(x,y,x,a) x+2*y-4*a 
Error: repeated formal argument 'x' on line 1 

R ठीक से अवैध औपचारिक के लिए मेरे परिभाषित समारोह जाँच करता है।

लेकिन यदि मैं ऊपर मैन्युअल रूप से बेईमानी से बातें:

ffoo<-function(x,y,a) x+2*y-4*a 
formals(ffoo)<-c(x=7, formals(ffoo)) 

तब मैं केवल बाहर कुछ परिस्थितियों है कि कुछ अवैध है के तहत मिल जाएगा। ffoo(3,4,5,6) ठीक से निष्पादित करेगा (हालांकि शायद मुझे वह उत्तर नहीं दे रहा है), जैसा कि ffoo(y=3,a=2) होगा; जबकि ffoo(x=5,y=3,a=2) संदिग्ध तर्क नामों के बारे में एक त्रुटि फेंक देगा।

तो क्या कोई मौजूदा फ़ंक्शन के formals पर 'सैनिटी' जांच करने के लिए कोई फ़ंक्शन के साथ base-R या उन्नत उपयोगिता पैकेज है?

+1

मैं एक अनुसंधान समारोह नहीं मिल सकता है, लेकिन आप सी पढ़ सकते हैं [src/main/gram.y] पर कोड (https://github.com/wch/r-source/blob/cf829c12299b8571cd67e9d8aae88ac31450c73c/src/main/gram.y)। फ़ंक्शन 'चेकफॉर्मलअर्ग्स() ' – Andrie

+1

@ रिचर्डस्क्रिवन नंबर के लिए खोजें, मैंने वर्ष का जवाब स्वीकार कर लिया है। मेरा अंतिम समाधान 'फॉर्मल्स' में वास्तविक नामों को पार करना और मैचों में से 'do.call' बनाना था। मैं इसे "उत्तर-विस्तार" के रूप में पोस्ट करूंगा –

उत्तर

4

संपादित करें:

आप बस डुप्लिकेट किए गए तर्क के लिए जाँच करना चाहते हैं, तो आप ऐसा कर सकते हैं:

any(duplicated(names(formals(ffoo)))) 
# [1] TRUE 

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


मूल जवाब:

रूप the C code pointed to by Andrie में की ओर संकेत किया गया है, इस जाहिरा तौर पर एक जांच है कि जब (का मूल्यांकन नहीं) को पार्स function() के लिए एक कॉल आर करता है। यही कारण है कि आप formals<- पर अपनी कॉल के साथ चेक को बाधित करने में सक्षम थे, और यही कारण है कि निम्नलिखित (उदाहरण के लिए) भी चेक प्राप्त करने से बचाता है। दोनों स्थितियों में, फ़ंक्शन को function() पर कॉल को पार्स किए बिना संशोधित/बनाया गया है।

eval(call("function", formals(ffoo), body(ffoo))) 
# function (x = 7, x, y, a) 
# x + 2 * y - 4 * a 

आर के पार्स मशीनरी आम तौर पर उपयोगकर्ता के लिए दृश्यमान आर कार्यों में उजागर नहीं कर रहा है, तो मैं वहाँ कोई रेडीमेड समारोह आर इस जाँच करने के लिए समारोह है लगता है कि होगा। हालांकि, आप चेक के सटीक उसी सेट को निष्पादित कर सकते हैं जो आर करता है जब आप अभिव्यक्ति को स्रोत करते हैं या फ़ंक्शन परिभाषा को अपने चरित्र प्रतिनिधित्व में परिवर्तित करके कमांड लाइन पर दर्ज करते हैं और फिर इसे स्वयं को फिर से पार्स करने का प्रयास करते हैं।

parse(text = capture.output(dput(ffoo))) 
# Error in parse(text = capture.output(dput(ffoo))) : 
# repeated formal argument 'x' on line 1 

एक समारोह के रूप जाँच लपेट के लिए कुछ इस तरह करते हैं:

यहाँ सामान्य विचार है

isParseableFunction <- function(x) { 
    tryCatch(is.function(x) & 
      is.expression(parse(text = capture.output(dput(x)))), 
      error = function(e) FALSE) 
} 

isParseableFunction(data.frame) 
# [1] TRUE 
isParseableFunction(mean) 
# [1] TRUE 
isParseableFunction(ffoo) 
# [1] FALSE 
isParseableFunction(99) 
# [1] FALSE 
+0

क्यों न केवल 'डुप्लीकेट (नाम (फॉर्मल्स (एफएफयू)) देखें?)? – hadley

+0

@ हैडली - वह (या, वास्तव में, 'कोई भी (डुप्लीकेट (विधियां :: औपचारिक आर्ग्स ("एफएफयू"))) ') मेरा पहला विचार भी था, लेकिन मैंने एक ऐसा समाधान देने का फैसला किया जो किसी अन्य संभावित अज्ञात- मुझे जांचता है कि आर प्रदर्शन करता है। (यही कारण है कि मेरा जवाब "प्रदर्शन करता है जो चेक का सटीक सेट है [...]") –

+0

समस्या यह है कि आप 'dput()' के खिलाफ व्यापार कर रहे हैं जो आपको फ़ंक्शन का अच्छा प्रतिनिधित्व दे रहा है - I अतीत में पर्याप्त समस्याएं थीं, मुझे इस पर भरोसा नहीं है। – hadley

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