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"