Disons que j'ai une fonction f
qui prend un tas d'arguments, avec un argument supplémentaire optionnel.Propre façon d'effectuer une évaluation paresseuse imbriquée dans rlang
f <- function(..., extra)
{
arglst <- lapply(quos(...), get_expr)
if(!missing(extra))
{
extra <- get_expr(enquo(extra))
arglst <- c(arglst, extra=extra)
}
arglst
## ... do something with argument list ... ##
}
f(a, extra=foo)
# [[1]]
# a
#
# $extra
# foo
Notez que je ne veux pas évaluer les arguments en tant que tel, mais je ne veux obtenir les expressions qui ont été transmis, à évaluer par tout autre code la ligne.
Le nouveau package rlang (qui alimente la prochaine version de dplyr, qui sera publiée sur CRAN Real Soon Now) fournit de nombreuses fonctionnalités pour l'évaluation paresseuse que j'utilise dans f
ci-dessus. Par exemple quos
, get_expr
et enquo
sont toutes les fonctions de rlang.
Dans f
, la partie où je traite extra
est en fait le code standard: je vais le faire dans d'autres fonctions, pas seulement dans f
. Je ne veux pas réécrire à chaque fois, donc je pensais que je mettrais dans sa propre fonction:
doExtra <- function(arglst, extra)
{
if(!missing(extra))
{
extra <- get_expr(enquo(extra))
arglst <- c(arglst, extra=extra)
}
arglst
}
f2 <- function(..., extra)
{
arglst <- lapply(quos(...), get_expr)
arglst <- doExtra(arglst, extra)
arglst
}
Le problème est que quand je le fais de cette façon, la valeur de extra
que doExtra
voit est ce qui est passé dans de f2
, et non l'original:
f2(a, extra=foo)
# [[1]]
# a
#
# $extra
# extra
Comment puis-je modifier f
pour isoler le code passe-partout, sans obtenir le mauvais résultat? Je peux faire quelque chose comme manipuler l'environnement de la trame d'appel doExtra
directement, mais ce serait extrêmement moche.
L'utilisation de quosures est problématique car le code en aval fait son propre NSE. Le code extra_by_expression ne fonctionne pas pour moi (il semble que l'analyse de '!!' soit '! (! (...))') mais la valeur extra_by_value fonctionne. Merci. –
Je dirais qu'il n'utilise pas les quosures qui posent problème, il fait NSE de manière non-ordonnée;) – lionel
J'ai essayé quelque chose de similaire: 'outer (nomColonne)' appelant 'inner (nomColonne)' appelant les fonctions dplyr en utilisant 'columnName' . Les deux 'outer' et' inner' utilisent 'enquo' et ensuite' !! '. 'inner' fonctionne seul, mais' outer' ne fonctionne pas. Que voulez-vous dire en utilisant NSE d'une manière non-rangé? –