For an arbitrary expression or string, define the variables necessary to execute the expression

Say I have a simple expression, for example:

ifelse(x < 0, 1,0)

I would like to pass this to some function, for example all.varsprovided by @RichScriven. Thus, the result will be a character vector:x

rowSums(dat[c("x","y","z")]) 

In this case, I would like to see: c("dat", "x","y","z").

However, there are more complex examples:

ifelse(x < 0, rowsums(dat[c("x","y","z"]), 0)

In this case, I would like to see: c("x", "dat", "x","y","z")

It seems that he answered the first part of my question all.vars, but this does not work for the second part.

+4
source share
1 answer

The following should do what you want:

recurse_ast <- function(x) {
  if (is.atomic(x) || is.name(x)){}
  else if (is.call(x)) {
    if(identical(quote(`[`),x[[1]])) {
      ret <- c()
      for(i in seq(2,length(x))) {
        if(is.call(x[[i]]) && x[[i]][[1]] == 'c') {
          for(j in seq(2,length(x[[i]]))) {
            if(!is.name(x[[i]][[j]])){
              ret <- c(ret,x[[i]][[j]]) 
            }
          }
        }
      }
      ret
    } else unlist(lapply(x,recurse_ast))
  } else if (is.pairlist(x) || is.expression(x)) {
      unlist(lapply(x,recurse_ast))
  } else {
    # User supplied incorrect input
    stop("Don't know how to handle type ", typeof(x), 
         call. = FALSE)
  }
}

get_requirements <- function(x) {
  c(all.vars(x),recurse_ast(x))
}

( ):

> get_requirements(quote(ifelse(x < 0, 1,0)))
[1] "x"
> get_requirements(quote(rowSums(dat[c("x","y","z")])))
[1] "dat" "x"   "y"   "z"  
> get_requirements(quote(ifelse(x < 0, rowsums(dat[c("x","y","z")], 0))))
[1] "x"   "dat" "x"   "y"   "z" 

: , , , recurse_ast all.vars , x "x", , , , , .

: , :

> get_requirements_from_string <- function(s) {
+   get_requirements(parse(text=s))
+ }
> get_requirements_from_string("ifelse(x < 0, 1, 0)")
 [1] "x"
+4

Source: https://habr.com/ru/post/1668195/


All Articles