Sorry for the confusing title and this might be a confusing question as well but I will try my best to explain.
Below is a very simplified example of my function. My original function is complex with many more arguments.
I have a function -
library(magrittr) #for pipes
parent_fn <- function(x = 5, y = 1, z = 10) {
xy <- function() {
x y
}
create_file_from_function(xy, 'fn.R')
}
and create_file_from_function
is defined as
create_file_from_function <- function(fn, path) {
fn_str <- deparse(substitute(fn))
fn %>%
capture.output() %>%
head(-1) %>% #To remove the last line "<environment: 0x....>"
paste0(collapse = '\n') %>%
paste(fn_str, '<-', .) %>%
cat(file = path)
}
What create_file_from_function
does is it copies the body of the function in a new file as passed in path
.
When I call
parent_fn()
In my working directory it creates a new file fn.R
with the text -
xy <- function() {
x y
}
However, what I would like to have is the below -
xy <- function() {
5 1
}
which means the default values from parent_fn
should be evaluated and passed in the new file.
Similarly, below are some more function calls and expected output just to make sure I have explained my problem clearly.
parent_fn
call :
parent_fn(x = 10)
Expected output in fn.R
xy <- function() {
10 1
}
parent_fn
call :
parent_fn(x = 10, y = 2)
Expected output in fn.R
xy <- function() {
10 2
}
I have tried using eval
and did some other attempts looking online but honestly, I have no idea how I can achieve this.
Thank you for your time.
CodePudding user response:
You can use substitute()
and pass the variables to its environment argument:
parent_fn <- function(x = 5, y = 1, z = 10, out = "fn.R") {
f <- substitute(`<-`(xy, function() {
x y
}), list(x = x, y = y, z = z))
writeLines(deparse(f), out)
}
parent_fn()
Generates a file containing:
xy <- function() {
5 1
}