So let's say that I want to now if X
appears in the quosure.
library(rlang)
library(purrr)
q <- quo(mean(X))
I know I can check for equality with expr
q[[2]][[2]] == expr(X)
[1] TRUE
But how do I iterate or flatten the quo element? flatten(q)
doesn't work, I couldn't use for loops, no idea how to use some map function from purrr
.
Ideally I would like to capture X when it's "data" and not any function.
I use the following custom function to convert expressions to their Abstract Syntax Trees (ASTs):
getAST <- function( ee ) { as.list(ee) %>% purrr::map_if(is.call, getAST) }
Since you're working with quosures, there's an intermediate step of retrieving the associated expression:
## 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
From here, you can use standard techniques to find X
. For example, flatten the nested list and compare each element to expr(X)
as in your question:
purrr::has_element( unlist(ast), expr(X) )
# [1] TRUE
purrr::map_lgl( unlist(ast), identical, expr(X) )
# [1] FALSE FALSE FALSE FALSE TRUE FALSE