2010-10-06 1 views
3

J'ai un code où il est plus pratique d'appeler fix via do.call, plutôt que directement. Tout ancien cadre de données fonctionnera pour cet exemple:Pouvez-vous utiliser le correctif via do.call?

dfr <- data.frame(x = 1:5, y = letters[1:5]) 

La première tentative évidente est

do.call("fix", list(dfr)) 

Malheureusement, cela ne fonctionne pas avec

Error in fix(list(x = 1:5, y = 1:5)) : 'fix' requires a name 

, nous donnons donc un nom:

do.call("fix", list(dfr = dfr)) 

cette fois-ci avec NIT

Error in is.name(subx) : 'subx' is missing 

Pour mémoire, edit ne fonctionne pas non plus.

dfr <- do.call("edit", list(dfr = dfr)) 

Quelqu'un peut-il penser à une solution de contournement raisonnable, s'il vous plaît?

EDIT: Après réflexion, j'avais oublié que fix déversait toujours sa réponse dans l'environnement global, ce qui est bien pour les exemples de test, mais pas si bon pour une utilisation avec des fonctions. L'excellente solution de contournement de Joshua ne s'étend pas à utiliser avec edit.

Pour les points bonus, comment appelez-vous edit via do.call?

Répondre

7

Vous pouvez utiliser substitute, qui est également utile lorsque vous souhaitez utiliser des noms de variables comme les étiquettes.

do.call("fix",list(substitute(dfr))) 

Modifier pour plus de clarté

Il est plus facile de voir comment cela fonctionne en utilisant la commande call:

> call("fix",dfr) 
fix(list(x = c(1, 2, 3, 4, 5), y = 1:5)) 
> call("fix",substitute(dfr)) 
fix(dfr) 

Ainsi, lorsque vous utilisez substitute la commande qui est en cours de création utilise la nom du symbole plutôt que du symbole évalué. Si vous entourez un eval autour de ces expressions, vous voyez que le premier exemple donne la même erreur que vous avez rencontrée et le second exemple fonctionne comme prévu.

Après avoir lu le lien de hadley il devient plus clair ce qui est en cours d'évaluation:

> as.name("dfr")==substitute(dfr) 
[1] TRUE 
+0

Cela fonctionne également pour 'edit'. Hourra! –

+0

Je trouve que chaque fois que j'utilise 'substitute' a été précédé d'une session prolongée de tourettes induites par la programmation. Si quelqu'un connaît une explication simple de comment et quand l'utiliser, je serais reconnaissant. –

+2

@Richie: essayez http://github.com/hadley/devtools/wiki/Evaluation – hadley

3

La première erreur vous donne un indice. Cela fonctionne:

do.call(fix,list("dfr")) 

Vous obtenez toujours la même erreur sur votre deuxième essai, même si vous avez utilisé dfr="dfr" parce que la liste nommée a besoin des noms des arguments à what (la fonction). Donc, votre deuxième essai devrait être:

do.call(fix,list(x="dfr")) 
+0

@Johua: Doh! Je me sens légèrement bête. À votre santé. –

+0

@Richie: essayez aussi la réponse de James, car elle ressemble plus à un R. –

+0

@Joshua: Marquer James comme la réponse officielle, en raison de la façon dont il résout le problème de 'edit' aussi, mais rappelez-moi que je vous dois un upvote supplémentaire pour cette excellente réponse rapide. –