как перебрать внутри элементов квеста Rlang в R - PullRequest
0 голосов
/ 01 октября 2018

Итак, скажем, что я хочу сделать это сейчас, если в предложении появится X.

library(rlang)
library(purrr)
q <- quo(mean(X))

Я знаю, что могу проверить равенство с помощью expr

q[[2]][[2]] == expr(X)
[1] TRUE

Но как это сделать?Я повторяю или выравниваю элемент кво?flatten(q) не работает, я не мог использовать для циклов, не знаю, как использовать какую-то функцию карты из purrr.

В идеале я хотел бы захватить X, когда это «данные», а не какие-либофункция.

1 Ответ

0 голосов
/ 02 октября 2018

Я использую следующую пользовательскую функцию для преобразования выражений в их Абстрактные синтаксические деревья (ASTs):

getAST <- function( ee ) { as.list(ee) %>% purrr::map_if(is.call, getAST) }

Поскольку вы работаете с предложениями, есть промежуточный этап получениясоответствующее выражение:

## Define a quosure
## Side note: don't use q as a variable name; it conflicts with q()
qsr <- quo( mean(5*X+2) )

## The associated expression
xpr <- rlang::get_expr( qsr )

## ...and its AST
ast <- getAST( xpr )
# List of 2
#  $ : symbol mean
#  $ :List of 3
#   ..$ : symbol +
#   ..$ :List of 3
#   .. ..$ : symbol *
#   .. ..$ : num 5
#   .. ..$ : symbol X
#   ..$ : num 2

Здесь вы можете использовать стандартные методы, чтобы найти X.Например, выровняйте вложенный список и сравните каждый элемент с expr(X), как в вашем вопросе:

purrr::has_element( unlist(ast), expr(X) )
# [1] TRUE

purrr::map_lgl( unlist(ast), identical, expr(X) )
# [1] FALSE FALSE FALSE FALSE  TRUE FALSE
...