2015-03-08 3 views
6

Ich möchte eine optionale Variable zu einer Funktion liefern, lassen Sie die Funktionen überprüfen, ob dieses Argument geliefert wurde, und lassen Sie es die entsprechende Menge ausführen von Berechnungen. Ich dachte, ich könnte den Operator '...' dafür benutzen.R: Finden Sie Variablen, die Funktionen mit dem '...' Argument mit exists() übergeben werden

Das einfachste Beispiel, das ich mir vorstellen kann ist dies (die leider nicht):

monkeyfun = function(...){ 

    if (exists("monkey")){ 
     return('monkey found') 
    } else { 
     return('monkey not found') 
    } 

    } 

Jetzt monkeyfun(monkey=0) sowie monkeyfun() beide Rück "monkey not found".

Als Plausibilitätsprüfung funktioniert die Definition monkey = 1 außerhalb der Funktion und gibt "monkey found" zurück.

Die Dokumentation auf dem '...' Argument hilft mir nicht wirklich, dieses Problem zu verstehen, und ich war nicht in der Lage, eine Formulierung dieser Frage zu finden, die übereinstimmende Ergebnisse liefert (ich verstehe, dass diese Frage grundlegend ist und wahrscheinlich irgendwo diskutiert wird) ...

Ich würde wirklich einige Hilfe mit diesem schätzen.

Antwort

5

würde ich hasArg verwenden:

monkeyfun <- function(...) { 
    if (hasArg("monkey")) { 
    return('monkey found') 
    } else { 
    return('monkey not found') 
    } 
} 
monkeyfun() 
# [1] "monkey not found" 
monkeyfun(monkey=0) 
# [1] "monkey found" 
+0

klar die beste Option – BrodieG

+0

Ich spielte gerade mit 'hasArg()' gerade jetzt ... es zeigte das folgende unerwartete Verhalten obwohl ... nehmen Sie die folgende Funktion: 'tfun = Funktion (x = 0) {if (hasArg (name = 'x')) {print ('found')}} ' Wenn ich es ohne Angabe von' x' ausführe (was trotzdem den Standard auslösen sollte), sagt es mir nicht "gefunden" '. – Affaeng

+0

@Affaeng: Warum ist das unerwartet? Wenn Sie 'tfun()' ohne Argumente aufrufen, dann gibt es kein Argument 'x' im Aufruf. Also 'hasArg (" x ")' gibt ganz richtig 'FALSE' zurück. Es ist irrelevant, dass 'x' ein formales Argument für' tfun' ist. Wie im Abschnitt * Siehe auch * zu '? HasArg' erwähnt, möchten Sie vielleicht '? Missing' lesen. –

1

Dies hat damit zu tun, wie die nicht standardmäßige Auswertung in R funktioniert (http://adv-r.had.co.nz/Computing-on-the-language.html#capturing-dots). Sie können eine Liste der an die Funktion übergebenen Objekte mit ... unter Verwendung von print(list(...)) drucken. Sie können sie mit eval(substitute(alist(...))) auswerten. In Ihrem Fall möchten Sie überprüfen, ob ein Objekt in ... definiert ist. Dies kann durch den folgenden Code erreicht werden.

monkeyfun = function(...){ 
print(list(...)) 
    if ("monkey"%in%names(list(...))){ 
    return('monkey found') 
    } else { 
    return('monkey not found') 
    } 

} 
+4

Der Mechanismus von Hadley angeboten wird, ist nicht typisch R Praxis. Es ist typischer, das Ergebnis von 'list (...)' einem Namen zuzuweisen und dann mit diesem Objekt zu arbeiten, vielleicht in Kombination mit 'match.arg'. Ich denke auch nicht, dass dies viel mit Nicht-Standard-Bewertung zu tun hat –

3

Sehen Sie sich diesen Dialog mit dem R-Interpreter an. Im allgemeinen Existenz durch Sehen getestet, wenn die Länge größer als 0:

monkeyfun = function(...){ 
print(str(list(...))) 
    } 
monkeyfun(monkey=0) 
#List of 1 
# $ monkey: num 0 
#NULL 
monkeyfun = function(...){ 
loclist = list(...) 
    if (exists(loclist$monkey)){ 
     return('monkey found') 
     } else { 
     return('monkey not found') 
     } } 
monkeyfun(monkey=0) 
#Error in exists(loclist$monkey) : invalid first argument 
monkeyfun = function(...){ 
loclist = list(...) 
    if (length(loclist$monkey)){ 
     return('monkey found') 
     } else { 
     return('monkey not found') 
     } } 
monkeyfun(monkey=0) 
#[1] "monkey found" 
monkeyfun(monk_uncle=1) 
#[1] "monkey not found" 
4

ich match.call verwenden würden, da sie mit ihrem vollständigen Namen alle Funktionsargumente angegeben zurück. Hier, wie ich Ihre Funktion neu schreiben würde:

monkeyfun = function(...){ 
    params <- as.list(match.call()[-1]) 
    if ("monkey" %in% names(params)){ ## note how I change the test here 
    return('monkey found') 
    } else { 
    return('monkey not found') 
    } 

} 

# monkeyfun() 
# [1] "monkey not found" 
# > monkeyfun(monkey=0) 
# [1] "monkey found" 
+0

Vielen Dank! – Affaeng

+0

Ich denke 'params <- list (...)' ist ein wenig einfacher und leichter zu verstehen. Ich glaube, es wird hier genauso funktionieren. –

Verwandte Themen