Pouvez-vous utiliser fix via do.call?
Question
J'ai un code où il est plus commode d'appeler fix
via do.call
, plutôt que directement. Tout ancien cadre de données fonctionnera pour cet exemple:
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
Alors, on lui donne un nom:
do.call("fix", list(dfr = dfr))
Cette fois, il échoue avec
Error in is.name(subx) : 'subx' is missing
Pour l'enregistrement, edit
ne fonctionne pas non plus.
dfr <- do.call("edit", list(dfr = dfr))
Quelqu'un peut-il penser à une solution raisonnable, s'il vous plaît?
EDIT: Après réflexion, je l'avais oublié que fix
provoque toujours un plantage sa réponse dans l'environnement mondial, ce qui est bien pour des exemples de test, mais pas si bon pour une utilisation avec des fonctions. une excellente solution de Joshua ne va pas utiliser avec edit
.
Pour les points bonus, comment appeler edit
via do.call
-vous?
La solution
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 le nom du symbole plutôt que le symbole évalué. Si vous enveloppez un eval
autour de ces expressions que vous voyez que le premier exemple donne la même erreur que vous rencontrez, 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
Autres conseils
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"))