huxfurpaw huxfurpaw - 1 month ago 17
R Question

R functions that execute functions

I'm trying to break out common lines of code used in a fairly large R script into encapsulated functions...however, they don't seem to be running the intended code when called. I feel like I'm missing some conceptual piece of how R works, or functional programming in general.

Examples:

Here's a piece of code I'd like to call to clear the workspace -

clearWorkSpace <- function() {
rm(list= ls(all=TRUE))
}


As noted, the code inside of the function executes as expected, however if the parent function is called, the environment is not cleared.

Again, here's a function intended to load all dependency files -

loadDependencies <- function() {
dep_files <- list.files(path="./dependencies")
for (file in dep_files) {
file_path <- paste0("./dependencies/",file)
source(file_path,local=TRUE)
}
}


If possible, it'd be great to be able to encapsulate code into easy to read functions. Thanks for your help in advance.

Answer

What you are calling workspace is more properly referred to as the global environment.

Functions execute in their own environments. This is, for example, why you don't see the variables defined inside a function in your global environment. Also how a function knows to use a variable named x defined in the function body rather than some x you might happen to have in your global environment.

Most functions don't modify the external environments, which is good! It's the functional programming paradigm. Functions that do modify environments, such as rm and source, usually take arguments so that you can be explicit about which environment is modified. If you look at ?rm you'll see an envir argument, and that argument is most of what its Details section describes. source has a local argument:

local - TRUE, FALSE or an environment, determining where the parsed expressions are evaluated. FALSE (the default) corresponds to the user's workspace (the global environment) and TRUE to the environment from which source is called.

You explicitly set local = TRUE when you call source, which explicitly tells source to only modify the local (inside the function) environment, so of course your global environment is untouched!


To make your functions work as I assume you want them to, you could modify clearWorkSpace like this:

clearWorkSpace <- function() {
  rm(list= ls(all=TRUE, envir = .GlobalEnv), envir = .GlobalEnv)
}

And for loadDependencies simply delete the local = TRUE. (Or more explicitly set local = FALSE or local = .GlobalEnv)