William Mitchell
William Mitchell

Reputation: 101

Can I prevent subfunctions from returning to R environment after running custom function?

Setup:

Say I have two R functions, x() and y().

# Defining function x 
# Simple, but what it does is not really important.
x <- function(input)
{output <- input * 10
  return(output)}

x() is contained within an .R file and stored in the same directory as y(), but within a different file.

# Defining function y; 
# What's important is that Function y's output depends on function x
y <- function(variable){
  source('x.R')
  output <- x(input = variable)/0.5
    return(output)
}

When y() is defined in R, the environment populates with y() only, like such: After defining function y

However, after we actually run y()...

# Demonstrating that it works
> y(100)
[1] 2000

the environment populates with x as well, like such: R environment after using the function

Question:

Can I add code within y to prevent x from populating the R environment after it has ran? I've built a function that's dependent upon several source files which I don't want to keep in the environment after the function has run. I'd like to avoid unnecessarily crowding the R environment when people use the primary function, but adding a simple rm(SubFunctionName) has not worked and I haven't found any other threads on the topic. Any ideas? Thanks for your time!

Upvotes: 0

Views: 105

Answers (1)

G. Grothendieck
G. Grothendieck

Reputation: 269596

1) Replace the source line with the following to cause it to be sourced into the local environment.

source('x.R', local = TRUE)

2) Another possibility is to write y like this so that x.R is only read when y.R is sourced rather than each time y is called.

y <- local({
  source('x.R', local = TRUE)
  function(variable) x(input = variable) / 0.5
})

3) If you don't mind having x defined in y.R then y.R could be written as follows. Note that this eliminates having any source statements in the code separating the file processing and code.

y <- function(variable) {
  x <- function(input) input * 10
  x(input = variable) / 0.5
}

4) Yet another possibility for separating the file processing and code is to remove the source statement from y and read x.R and y.R into the same local environment so that outside of e they can only be accessed via e. In that case they can both be removed by removing e.

e <- local({
  source("x.R", local = TRUE)
  source("y.R", local = TRUE)
  environment()
})

# test
ls(e)
## [1] "x" "y"
e$y(3)
## [1] 60

4a) A variation of this having similar advantages but being even shorter is:

e <- new.env()
source("x.R", local = e)
source("y.R", local = e)

# test
ls(e)
## [1] "x" "y"
e$y(3)
## [1] 60

5) Yet another approach is to use the CRAN modules package or the klmr/modules package referenced in its README.

Upvotes: 1

Related Questions