È possibile utilizzare correzione tramite do.call?
Domanda
Ho qualche codice in cui è più conveniente per chiamare fix
via do.call
, piuttosto che direttamente. Qualsiasi vecchio telaio dati lavorerà per questo esempio:
dfr <- data.frame(x = 1:5, y = letters[1:5])
L'ovvio primo tentativo è
do.call("fix", list(dfr))
Purtroppo, questo non funziona con
Error in fix(list(x = 1:5, y = 1:5)) : 'fix' requires a name
Quindi, diamo un nome:
do.call("fix", list(dfr = dfr))
Questa volta non riesce con
Error in is.name(subx) : 'subx' is missing
Per la cronaca, edit
non funziona neanche.
dfr <- do.call("edit", list(dfr = dfr))
Qualcuno può pensare ad una soluzione ragionevole, per favore?
EDIT: Su riflessione, avevo dimenticato che fix
discariche sempre la sua risposta nel contesto globale, che va bene per gli esempi di prova, ma non così buono per l'utilizzo con le funzioni. eccellente soluzione di Joshua non si estende da usare con edit
.
Per i punti bonus, come si fa a chiamare edit
via do.call
?
Soluzione
È possibile utilizzare substitute
, che è anche utile quando si desidera utilizzare nomi di variabili come etichette.
do.call("fix",list(substitute(dfr)))
Modifica per chiarezza
E 'più facile per vedere come funziona usando il comando call
:
> call("fix",dfr)
fix(list(x = c(1, 2, 3, 4, 5), y = 1:5))
> call("fix",substitute(dfr))
fix(dfr)
Così, quando si utilizza il comando substitute
che si sta creando utilizza il nome del simbolo, piuttosto che il simbolo valutata. Se si avvolgono un eval
intorno a queste espressioni si vede che il primo esempio dà lo stesso errore che si è verificato, e il secondo esempio funziona come previsto.
Dopo aver letto il legame di Hadley diventa più chiaro ciò che è in corso di valutazione:
> as.name("dfr")==substitute(dfr)
[1] TRUE
Altri suggerimenti
Il primo errore si dà un suggerimento. Questo funziona:
do.call(fix,list("dfr"))
Si potrebbe ancora ottenere lo stesso errore sul secondo tentativo, anche se è stato utilizzato dfr="dfr"
perché l'elenco di nome ha bisogno di nomi degli argomenti per what
(la funzione). Così il vostro secondo tentativo dovrebbe essere:
do.call(fix,list(x="dfr"))