Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to insert expression into the body of a function in R

Tags:

r

I have a function f <- function(x){x}. I want to insert the line x <- 2*x into f such that it ends up as

function(x){
    x <- 2*x
    x
}

I understand that I should be using body(), but I have thus far only figured out how to replace the entire body, which is not practical for my true purposes.

like image 620
BioBroo Avatar asked Feb 07 '23 10:02

BioBroo


2 Answers

Here's another way (using magrittr to streamline things)

f <- function(x){x}
f(2)
# [1] 2
# library(magrittr)
body(f) <- body(f) %>% as.list %>% append(quote(x<-2*x), 1) %>% as.call
f(2)
# [1] 4

Or even simply

body(f) %<>% as.list %>% append(quote(x<-2*x), 1) %>% as.call %>% as.expression

but I feel like I may be missing an en even simpler way

You could write a more traditional function without magrittr as well...

funins <- function(f, expr = expression(x<-2*x), after=1) {
    body(f)<-as.call(append(as.list(body(f)), expr, after=after))
    f
}

Which you can use to insert any expression

f <- function(x){x}
g <- funins(f, expression(print("hi"), x<-3*x))
f(2)
# [1] 2
g(2)
# [1] "hi"
# [1] 6
like image 109
MrFlick Avatar answered Feb 08 '23 23:02

MrFlick


Here is my comment as an answer. THe if else protects in case it's a single line fuunction:

f <- function(x){x}


fun <- f

bod <- body(fun)
if (trimws(as.character(bod[[1]])) == "{"){
    body(fun)[[2]] <- quote(x <- 2*x)
    if (length(bod) > 1) body(fun)[3:(1+length(bod))] <- bod[-1]
} else {
    body(fun)[[1]] <- as.name('{')
    body(fun)[[2]] <- quote(x <- 2*x)
    body(fun)[[3]] <- bod
}
fun
fun(3)
like image 21
Tyler Rinker Avatar answered Feb 08 '23 23:02

Tyler Rinker