theforestecologist
theforestecologist

Reputation: 4917

How do I include sourced code into a function in R?

I have a function I wrote and saved in a .R file. I want to source the code in another .R file while modifying it.

For example, What I want is:

file1 code :

func <- function(x=x) {sum(x)}

file2 code:

func2 <- function(x) {source('file1.R')}
func2(x=c(2:3))
[1] 5

However, this doesn't seem to work.

Upvotes: 2

Views: 104

Answers (3)

G. Grothendieck
G. Grothendieck

Reputation: 269526

Note that a significant advantage of these solutions is that they don't re-read file1.R each time func2 runs.

1) source into workspace The source call will define func and then we define func2 to be the same as func and finally we optionally remove func. At this point we can run func2.

source('file1.R')
func2 <- func
rm(func) # optional
func2(x=c(2:3))

2) source into local environment An alternative would be to source the file defining func in a local environment and assign the last statement in the local environment to func2; however, func2 itself is outside the local environment. After the definition of func2, func will not be visible but func2 will be. Note that the source statement is only run once and only func is assigned to func2 so that the source statement is not run each time func2 is run.

func2 <- local({
    source("file1.R", local = TRUE)
    func
})
func2(x=c(2:3))

3) modules package

After installing the modules package from github (this package gives you something half way between source and full R packages) try this:

# devtools::install_github('klmr/modules')

library(modules)

file1 <- import("file1")
func2 <- file1$func
func2(3:4)

Note: that in the question's definition of func in file1.R that the argument x=x will generate an error if x is not supplied by the caller since it will result in a self reference. What is really wanted is: func <- function(x) sum(x) or even just func <- sum.

Upvotes: 3

wolfste4
wolfste4

Reputation: 39

Right now, your code creates a function which sources 'file1.R' regardless of the x input. You need to tell the function to run the old function as well.

func2 <- function(x){
    source('file1.R',local=TRUE)
    func(x)
}

Upvotes: 2

Alexey Shiklomanov
Alexey Shiklomanov

Reputation: 1642

Try source("file1.R", local=TRUE). This will make the evaluation happen within the scope of the function rather than (the default behavior) the scope of the workspace.

But, as you currently have it written, it still won't work because your file1 is defining a function but not evaluating it.

To achieve the behavior you want, you'll want something like:

## file1.R ##
s <- sum(x)

## file2.R ##
func2 <- function(x) {
    source("file1.R", local=TRUE)
    return(s)
}
func2(x=c(2,3))

Upvotes: 3

Related Questions