3

I am sourcing util functions in production into an environment to encapsulate (and group) the helper functions:

Helper file:

# File: Helper.R
hello <- function() {
  print("Hello world")
}

Client:

helper <- new.env()
source("Helper.R", local=helper)
helper$hello()   # call the helper function

How can I migrate my sourced "Helper.R" into a library without breaking the calls of the sourced functions?

What I want is something like

helper <- new.env()
library(Helper, local=helper)
helper$hello()   # call the helper function (loaded from the library now)

Is there a way to do this?

R Yoda
  • 8,358
  • 2
  • 50
  • 87
  • Another way would be to source into a namespace (instead of an environment) and use `::` instead of `$`, but a question for this has no satifying answer: http://stackoverflow.com/q/15620404/4468078 – R Yoda Nov 20 '16 at 21:47

4 Answers4

1

You can use the box::use() function in the ‘box’ package.

Then the following attaches a package locally:

box::use(pkg[...])

Alternatively, and potentially closer to what you actually want to do, you could use the following simpler code:

box::use(pkg)

Now the package is not attached at all, and its exported objects can be accessed via pkg$obj. This is somewhat similar to base R’s loadNamespace function, but does considerably more behind the scenes.

Finally, consider not putting your helper code into a package at all, but rather distributing it as a module. This is after all what the ‘box’ package was designed for: instead of creating a package, just distribute your helper.r code file (or folder) and then use it as follows:

box::use(./helper)

See the package website and vignette for a detailed description.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • Great package, esp. the feature to make the function comments available as help (which `source` cannot do). I hope the `modules` package will find its way into CRAN soon – R Yoda Oct 16 '16 at 21:16
  • 1
    @RYoda Unfortunately it wasn’t soon, but the completely rewritten package [is now on CRAN](https://cran.r-project.org/package=box) under its new name, ‘box’. – Konrad Rudolph Mar 03 '21 at 17:19
1

Adding to the list of suggestions you can also consider to use the modules package on CRAN (note I am the author). When you have your Helper.R file with:

hello <- function() {
  print("Hello world")
}

you can use

helper <- modules::use("Helper.R")
helper$hello()

to encapsulate your helper functions in their own environment. The package also provides some functions to manipulate the local namespace of a module (imports/exports).

Sebastian
  • 840
  • 6
  • 11
0

Another way could be:

# getNamespace returns the environment representing the name space name. The namespace is loaded if necessary.
# Internal function to support reflection on namespace objects!
env <- getNamespace("data.table")
cars <- env$as.data.table(mtcars)

This examples makes all objects of the package data.table available via the environment variable env.

Note: It uses an internal R function (I have no idea how big the risk of changes of this internal function really is).

R Yoda
  • 8,358
  • 2
  • 50
  • 87
0

I have found another package called import (similar to "modules") that allows importing packages into an environment:

https://github.com/smbache/import

This package is also on CRAN:

install.packages("import")

It allows importing selected, all exported ("public") or all (even not exported) functions of a package.

Example:

import::from(dplyr, arrange, .into = "datatools")

The import::from function is a convenient wrapper around getExportedValue.

R Yoda
  • 8,358
  • 2
  • 50
  • 87