Home > Enterprise >  Evaluate arguments and pass them to new file
Evaluate arguments and pass them to new file

Time:11-25

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
}
  • Related