आर

2016-10-17 7 views
12

में फ़ंक्शंस की एक नई श्रेणी को परिभाषित करना, इसलिए मैं वर्णन कार्यों को जोड़ने के लिए आर में निर्माण कर रहे कुछ कार्यों की कक्षा बदल रहा हूं और क्योंकि मैं अपने लिए सबकुछ संभालने के लिए एस 3 जेनिक्स का उपयोग करना चाहता हूं। असल में, मैंआर

foo <- function(x) x + 1 

addFunction <- function(f, description) { 
    class(f) <- c("addFunction", "function") 
    attr(f, "description") <- description 
    f 
} 

foo <- addFunction(foo, "Add one") 

की तरह एक संरचना है और फिर मैं की तरह

description <- function(x) UseMethod("description") 
description.default <- function(x) deparse(substitute(x)) 
description.addFunction <- function(x) attr(x, "description") 

यह ठीक काम करता है सामान करते हैं, लेकिन यह है कि सुरुचिपूर्ण नहीं है। मैं सोच रहा हूं कि कार्यों की एक नई श्रेणी को परिभाषित करना संभव है जैसे कि इस वर्ग के उदाहरणों को function वाक्यविन्यास के समान वाक्यविन्यास में परिभाषित किया जा सकता है। दूसरे शब्दों में, इसे परिभाषित करने की addFunction ऐसी है कि foo निम्नलिखित तरीके से उत्पन्न होता है संभव है:

foo <- addFunction(description = "Add one", x) { 
    x + 1 
} 

(या कुछ इसी तरह, मैं कहाँ विशेषता समारोह में जोड़ा जाना चाहिए के बारे में कोई मजबूत भावनाओं है)?

पढ़ने के लिए धन्यवाद!


अद्यतन: मैं थोड़ा विचार के साथ अधिक प्रयोग किया, लेकिन वास्तव में अभी तक कोई ठोस परिणाम तक नहीं पहुंचे हैं - तो यह सिर्फ मेरे वर्तमान (अद्यतन) इस विषय पर विचार के एक सिंहावलोकन है:

मैंने function() -फंक्शन की प्रतिलिपि बनाने के विचार की कोशिश की, इसे एक अलग नाम दिया और फिर इसे बाद में जोड़ दिया। बहरहाल, यह काम नहीं करता है और मैं यहाँ क्या हो रहा है पर किसी भी जानकारी के प्यार होता:

> function2 <- `function` 
> identical(`function`, function2) 
[1] TRUE 
> function(x) x 
function(x) x 
> function2(x) x 
Error: unexpected symbol in "function2(x) x" 
> function2(x) 
Error: incorrect number of arguments to "function" 

function() के रूप में, एक आदिम समारोह है मैं और अधिक सुराग के लिए यह परिभाषित करने सी-कोड को देखकर की कोशिश की। मैं विशेष रूप से function2(x) कॉल से त्रुटि संदेश से चिंतित था। सी-कोड अंतर्निहित function()

/* Declared with a variable number of args in names.c */ 
    SEXP attribute_hidden do_function(SEXP call, SEXP op, SEXP args, SEXP rho) 
{ 
    SEXP rval, srcref; 

    if (TYPEOF(op) == PROMSXP) { 
    op = forcePromise(op); 
    SET_NAMED(op, 2); 
    } 
    if (length(args) < 2) WrongArgCount("function"); 
    CheckFormals(CAR(args)); 
    rval = mkCLOSXP(CAR(args), CADR(args), rho); 
    srcref = CADDR(args); 
    if (!isNull(srcref)) setAttrib(rval, R_SrcrefSymbol, srcref); 
    return rval; 
    } 

है और इस से, मैं निष्कर्ष है कि किसी कारण से, चार तर्क call, op, args और rho कम से कम दो अब आवश्यक हैं। do_function() के हस्ताक्षर से मैं अनुमान लगा रहा हूं कि चार तर्क do_function को पारित किया जाना चाहिए, एक वादा, तर्कों की एक सूची और फिर एक पर्यावरण होना चाहिए। मैं (शून्य पर इन तर्कों के दो करने के लिए सेट करने सहित) function2 के लिए विभिन्न संयोजनों का एक बहुत कोशिश की, लेकिन मैं एक ही (नया) त्रुटि संदेश प्राप्त हो:

> function2(call("sum", 2, 1), NULL, list(x=NULL), baseenv()) 
Error: invalid formal argument list for "function" 
> function2(call("sum", 2, 1), NULL, list(x=NULL), NULL) 
Error: invalid formal argument list for "function" 

यह त्रुटि संदेश सी से दिया जाता है समारोह CheckFormals(), जो मैं भी ऊपर देखा:

/* used in coerce.c */ 
    void attribute_hidden CheckFormals(SEXP ls) 
{ 
    if (isList(ls)) { 
    for (; ls != R_NilValue; ls = CDR(ls)) 
     if (TYPEOF(TAG(ls)) != SYMSXP) 
     goto err; 
    return; 
    } 
    err: 
    error(_("invalid formal argument list for \"function\"")); 
    } 

मैं नहीं धाराप्रवाह सी में सब पर तो यहां से पर मैं काफी आगे क्या करना है यकीन नहीं है हूँ,।

तो ये मेरी अद्यतन प्रश्न हैं:

  • क्यों function और function2 उसी तरह से व्यवहार नहीं करते? क्या मुझे function2 पर एक अलग वाक्यविन्यास का उपयोग करने की आवश्यकता है जब वे आर में समान समझा जाता है?
  • function2 के उचित तर्क क्या हैं function2([arguments]) वास्तव में एक फ़ंक्शन परिभाषित करेगा?
+3

मुझे नहीं लगता कि आप यह वास्तव में उस तरह से कर सकते हैं करते हैं:

अपने वर्तमान समस्या के लिए यहां एक ही समाधान है। आप 'addFunction (वर्णन = "एक जोड़ें", x)' और फ़ंक्शन बॉडी के बीच एक इंफिक्स ऑपरेटर का उपयोग कर सकते हैं। इन्फिक्स ऑपरेटर तब 'बॉडी <-'' कॉल करेगा। लेकिन मैं शायद एक कन्स्ट्रक्टर फ़ंक्शन को परिभाषित करता हूं जिसमें फ़ंक्शन तर्क और शरीर पैरामीटर के रूप में होता है। – Roland

+4

एक संभावित रूप से अधिक आर-आईश तरीका "विवरण <-" फ़ंक्शंस बनाना होगा, और फिर 'foo = function (x) {x * 2} करें; विवरण (एक्स) = "दोगुनी" ' – Spacedman

+0

धन्यवाद आप लोग :) कार्यक्षमता के मामले में दोनों निश्चित रूप से अच्छे समाधान हैं। लेकिन एक जिद्दी दृष्टिकोण से, मैं वास्तव में इसे फ़ंक्शन परिभाषा की तरह करना चाहूंगा। किसी ने मुझे एक बार कहा था कि आर वास्तव में सूचियों और कार्यों के अलावा कुछ भी नहीं है, लेकिन जाहिर है, यह वास्तव में सच नहीं है ... – AHP

उत्तर

2

आर में कुछ कीवर्ड जैसे if और function तरह से विशेष सिंटेक्स कि अंतर्निहित कार्यों कहा जाता हो सकते है। वांछित अगर एक समारोह के रूप में if का उपयोग करना काफी आसान है, उदा।

`if`(1 == 1, "True", "False") 

को

if (1 == 1) { 
    "True" 
} else { 
    "False" 
} 

function जटिल काम है बराबर है। a previous question पर इस पर कुछ मदद मिली है।

# Your S3 methods 
description <- function(x) UseMethod("description") 
description.default <- function(x) deparse(substitute(x)) 
description.addFunction <- function(x) attr(x, "description") 

# Creates the pairlist for arguments, handling arguments with no defaults 
# properly. Also brings in the description 
addFunction <- function(description, ...) { 
    args <- eval(substitute(alist(...))) 
    tmp <- names(args) 
    if (is.null(tmp)) tmp <- rep("", length(args)) 
    names(args)[tmp==""] <- args[tmp==""] 
    args[tmp==""] <- list(alist(x=)$x) 
    list(args = as.pairlist(args), description = description) 
} 

# Actually creates the function using the structure created by addFunction and the body 
`%{%` <- function(args, body) { 
    stopifnot(is.pairlist(args$args), class(substitute(body)) == "{") 
    f <- eval(call("function", args$args, substitute(body), parent.frame())) 
    class(f) <- c("addFunction", "function") 
    attr(f, "description") <- args$description 
    f 
} 

# Example. Note that the braces {} are mandatory even for one line functions 

foo <- addFunction(description = "Add one", x) %{% { 
    x + 1 
} 

foo(1) 
#[1] 2 
+0

धन्यवाद! मुझे लगता है कि ऐसा लगता है कि यह समाधान निकटतम है जिसे हम फ़ंक्शन() - वाक्यविन्यास में प्राप्त कर सकते हैं। लेकिन क्या आप समझते हैं कि _why_ 'function' मूल रूप से अन्य सभी चीज़ों से अलग है और हम इसे पूरी तरह से दोहराना क्यों नहीं कर सकते (जैसे हम' if' के साथ कर सकते हैं)? – AHP