Reputation: 1538
I am trying to find which set of functions are used in some code.
grepl("someFunction\\(", code)
over the function namesframe
does not get found in data.frame(...)
. This is possible with the following regex: grepl("[^a-zA-Z_\\.]someFunction\\(", code)
\\.
: gsub(".","\\.",theFunctions, fixed=TRUE)
Here's a minimal reproducible test:
code <- "mean(pi); head(data.frame(A=1:5)); data_frame(7:9)"
funs <- c("mean", "head", "head.data.frame", "data.frame", "frame", "data_frame")
data.frame(isfound=sapply(paste0("[^a-zA-Z_\\.]",gsub(".","\\.",funs,fixed=TRUE),"\\("),
grepl, x=paste0(" ",code)),
shouldbefound=c(T,T,F,T,F,T))
This seems to work, but is too long and not very human-readable.
Is there a more elegant way to determine which of a set of functions appear in some code?
Upvotes: 1
Views: 59
Reputation: 81733
You can use the following approach to find the names of the functions used in R code. The function get_functions
can be used with code represented as character string.
get_functions <- function(code) {
unname(find_functions(parse(text = code)))
}
find_functions <- function(x, y = vector(mode = "character", length = 0)) {
if (is.symbol(x)) {
if (is.function(eval(x)))
c(y, as.character(x))
} else {
if (!is.language(x)) {
NULL
} else {
c(y, unlist(lapply(x, find_functions)))
}
}
}
Here, find_functions
is called recursively since expressions can be nested.
An example:
code <- "mean(pi); head(data.frame(A=1:5)); data_frame(7:9)\n paste(\"ABC\", 0x28)"
get_functions(code)
# [1] "mean" "head" "data.frame" ":" "data_frame" ":" "paste"
This approach appears to be more safe since it makes use of R's parser. Furthermore, functions without parentheses can be found too (e.g., :
).
Upvotes: 2