I frequently have to create a function call inside another function, which is then to be evaluated. I tend to use eval(parse(text = "what_needs_to_be_done"))
for that, with the text constructed by using paste0()
. However, this does not feel like a good approach. Here is an example:
select_data <- function(x, A = NULL, B = NULL, C = NULL) {
kall <- as.list(match.call())
vars <- names(kall)[names(kall) %in% c("A", "B", "C")]
selection_criteria <- paste0(vars, " == ", kall[vars], collapse = ", ")
txt <- paste0("dplyr::filter(x, ", selection_criteria, ")")
res <- eval(parse(text = txt))
return(res)
}
DF <- data.frame(A = c(1,1,2,2,3,3), B = c(1,2,1,2,1,2), C = c(1,1,1,2,2,2))
select_data(DF, A = 2, C = 2)
This is only an example, in most cases the function to be constructed is more complex and extensive. However, the example shows the general problem. What I do now is first paste0
together the function call, the way I would enter it at the console and then evaluate it.
I have tampered with alternative approaches with substitute
, lazyeval
, bquote
, but I dont't quite understand what they really do and therefore can not get them to work.
Can you help me with finding a better way to contruct the call and subsequently evaluate it?