Following on from How to create an R function programmatically?
I want to build R functions from their components like this:
testfn <- function(..., expression){
args <- substitute(alist(...))
body <- substitute(expression)
eval(call("function", as.pairlist(eval(args)), body), parent.frame())
}
This works fine if there are default values:
testfn(x = 4, y = 5, expression = {
y <- y + 2
x + y
})
=>
function (x = 4, y = 5)
{
y <- y + 2
x + y
}
But it will not work if there is no default argument for one or more of the args:
testfn(x = 4, y, expression = {
y <- y + 2
x + y
})
=>
Error in eval(expr, envir, enclos) :
invalid formal argument list for "function"
I can put =
in the arg list to get this to work:
testfn(x = 4, y = , expression = {
y <- y + 2
x + y
})
=>
function (x = 4, y)
{
y <- y + 2
x + y
}
But I don't want to enforce this in the function arguments. I have tried editing the alist in the function, but when I do this, I get another invalid formal argument list error:
testfn2 <- function(..., expression){
args <- substitute(alist(...))
body <- substitute(expression)
for (arg in 2:length(args)){
if(names(myargs)[arg] == ""){
args[[arg]] <- as.name(paste(as.character(args)[arg], "="))
}
}
eval(call("function", as.pairlist(eval(args)), body), parent.frame())
}
testfn2(x = 4, y, expression = {
y <- y + 2
x + y
})
=>
Error in eval(expr, envir, enclos) :
invalid formal argument list for "function"
How can I change this so I can call testfn() with missing argument defaults? I thought of constructing a new alist from a character string using parse
but this will mean I cannot have e.g. functions as arguments.