2011-04-26 3 views
20

Vorrei fornire un argomento params a una funzione e quindi collegarlo in modo che possa utilizzare un parametro anziché un $ a ogni volta che faccio riferimento all'elemento list a.attach() all'interno della funzione

run.simulation<-function(model,params){ 
attach(params) 
# 
# Use elements of params as parameters in a simulation 
detach(params) 
} 

C'è un problema con questo? Se ho definito una variabile globale denominata c e ho anche definito un elemento denominato c della lista "params", il cui valore sarebbe stato usato dopo il comando attach?

risposta

25

Noah ha già sottolineato che l'uso di collegamento è una cattiva idea, anche se lo si vede in alcuni esempi e libri. C'è un modo per aggirare. Puoi usare "local attach" che si chiama with. Nell'esempio fittizio di Noah, sembrerebbe

with(params, print(a)) 

che restituirà un risultato identico, ma è più ordinato.

+4

+1 pena spiegare che cosa 'con()' e 'all'interno di()' fare. Nell'esempio fornito, 'with()' crea un ambiente da 'params' e quindi valuta l'espressione' print (a) '_inside_ quell'ambiente. Quindi i componenti di 'params' sono visibili quando l'espressione viene valutata, senza bisogno di' attach() 'loro. –

+0

Grazie mille per le risposte lucide. –

+0

Quindi ciò che ha funzionato alla fine era 'myFun <-function (model, params) {with (params), {...}}' dove ... è il corpo della funzione –

8

modo più semplice per risolvere i problemi ambito di questo tipo è di solito per provare qualcosa di semplice out:

a = 1 
params = c() 
params$a = 2 
myfun <- function(params) { 
    attach(params) 
    print(a) 
    detach(params) 
} 
myfun(params) 

Il seguente oggetto (s) sono mascherati _by_ .GlobalEnv:

a

# [1] 1 

Come puoi vedere, R sta riprendendo e attributo globale a qui.

è quasi sempre una buona idea per evitare di usare attach e detach ove possibile - portata finisce per essere difficile da gestire (per inciso, è anche meglio evitare nomi alle variabili c - R spesso capire che cosa ti riferisci a, ma ci sono così tante altre lettere là fuori, perché rischiare?). Inoltre, trovo il codice che utilizza attach/detach quasi impossibile da decifrare.

6

Un'altra possibilità è:

run.simulation <- function(model, params){ 
    # Assume params is a list of parameters from 
    # "params <- list(name1=value1, name2=value2, etc.)" 
    for (v in 1:length(params)) assign(names(params)[v], params[[v]]) 
    # Use elements of params as parameters in a simulation 
}