Is it possible in R to assign custom functions to mathematical operators (eg. *, +) or interpret the formulae supplied with as.formula() as a directive to evaluate?
Specifically, I would like * to be interpretted as intersect(), and + as c(), so R would evaluate the expression
(a * (b + c)) * d) OR myfun(as.formula('~(a * (b + c)) * d)'), list(a, b, c, d))
AS
intersect(intersect(a, c(b, c)), d)
I'm able to produce the same outcome with gsub()ing an expression supplied as string in a while() loop, but I guess it's far from perfection.
Edit: I've mistakenly posted sum() instead of c(), so some answers may refer to the unedited version of the question.
Example:
############################
## Define functions
var <- '[a-z\\\\{\\},]+'
varM <- paste0('(', var, ')')
varPM <- paste0('\\(', varM, '\\)')
## Strip parentheses
gsubP <- function(x) gsub(varPM, '\\1', x)
## * -> intersect{}
gsubI <- function(x) {
x <- gsubP(x)
x <- gsub(paste0(varM, '\\*', varM), 'intersect\\{\\1,\\2\\}', x)
return(x)
}
## + -> c{}
gsubC <- function(x) {
x <- gsubP(x)
x <- gsub(paste0(varM, '\\+', varM), 'c\\{\\1,\\2\\}', x)
return(x)
}
############################
## Set variables and formula
a <- 1:10
b <- 5:15
c <- seq(1, 20, 2)
d <- 1:5
string <- '(a * (b + c)) * d'
############################
## Substitute formula
string <- gsub(' ', '', string)
while (!identical(gsubI(string), string) || !identical(gsubC(string), string)) {
while (!identical(gsubI(string), string)) {
string <- gsubI(string)
}
string <- gsubC(string)
}
string <- gsub('{', '(', string, fixed=TRUE)
string <- gsub('}', ')', string, fixed=TRUE)
## SHAME! SHAME! SHAME! ding-ding
eval(parse(text=string))
You can do this:
Be aware that if you do that in the global environment (not a function) it will probably make the rest of your script fail unless you intend for * and + to always do sum and intercept. Other options would be to use S3 methods and classes to restrict that usage.
*and+have special meaning within formulae, so I don't think you can override that. But you can use a formula as a way of passing an unevaluated expression as per @MrFlick's answer.