2015-03-08 9 views
6

Voglio fornire una variabile facoltativa a una funzione, lasciare che le funzioni di verificare se questo argomento è stato fornito, e lasciare che si esegue il set corrispondente di calcoli. Pensavo di poter usare l'operatore '...' per quello.R: Trova le variabili in dotazione per le funzioni con il '...' argomento con exists()

L'esempio più semplice che posso pensare (che purtroppo non) è questo:

monkeyfun = function(...){ 

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

    } 

Ora monkeyfun(monkey=0) così come monkeyfun() entrambe ritorno "monkey not found".

Come controllo di integrità, la definizione di monkey = 1 al di fuori della funzione funziona e restituisce "monkey found".

La documentazione sull'argomento '...' non mi aiuta veramente a comprendere questo problema e non sono riuscito a trovare una formulazione di questa domanda che fornisca risultati di corrispondenza qui (so che questa domanda è di base e molto probabilmente discussa da qualche parte) ...

Vorrei davvero apprezzare un po 'di aiuto con questo.

risposta

5

vorrei utilizzare hasArg:

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

chiaramente la migliore opzione – BrodieG

+0

stavo giocando intorno con 'hasArg()' solo ora ... ha mostrato il seguente comportamento imprevisto però ... prendere la seguente funzione: 'tfun = function (x = 0) {if (hasArg (name = 'x')) {print ('trovato')}} ' Se l'eseguo senza fornire' x' (che dovrebbe comunque far scattare il default) che non mi dice ' "trovato"'. – Affaeng

+0

@Affaeng: perché è così inaspettato? Se chiami 'tfun()' senza argomenti, allora non c'è un argomento 'x' nella chiamata. Quindi 'hasArg (" x ")' restituisce correttamente 'FALSE'. È irrilevante che 'x' sia un argomento formale per' tfun'. Come menzionato nella sezione * Vedi anche * a '? HasArg', potresti voler leggere'? Missing'. –

1

questo ha a che fare con il modo di valutazione non standard lavora a R (http://adv-r.had.co.nz/Computing-on-the-language.html#capturing-dots). È possibile stampare un elenco degli oggetti passati alla funzione utilizzando ... utilizzando print(list(...)), è possibile valutare utilizzando eval(substitute(alist(...))). Nel tuo caso, vuoi verificare se un oggetto è definito in .... Questo può essere ottenuto con il seguente codice.

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

} 
+4

Il meccanismo offerto da Hadley non è tipica pratica R. È più tipico assegnare il risultato di 'list (...)' a un nome e quindi lavorare con quell'oggetto, magari in combinazione con 'match.arg'. Inoltre, non penso che questo abbia molto a che fare con la valutazione non standard –

3

Dai un'occhiata a questa finestra di dialogo con l'interprete R. Generalmente esistenza è testato da vedere se la lunghezza è maggiore di 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

userei match.call dal momento che restituisce tutti gli argomenti della funzione specificati con i loro nomi completi. Ecco Come faccio a riscrivere la funzione:

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

Grazie mille! – Affaeng

+0

Penso che 'params <- list (...)' sia un po 'più semplice e facile da capire. Credo che funzionerà lo stesso qui. –

Problemi correlati