Structuring and constructing modules part 3: Reading and adding data

When constructing modules, there are times you need a built-in data frames on those modules, list/atomic vectors, arrays/matrices, or any object outside from functions that represents the constant. Let’s explore how to effectively import / export and manage different types of data using {box}. Again, it could be an atomic vector, a list, a matrix, a data frame, an n-dimensional array, and so on. The basics of loading the data with {box} here is not rather lazy, unlike traditional R packages, the basics show you that you have to eagerly import them.

In this guide, especially for data frames later, let us use mpg dataset from the {ggplot2} package, and saved it as mpg.rds under data/ from ./module to load it via readRDS() function within the module.


Creating a module for the data

The steps are trivial, (almost) every steps are similar to how R packages handle the data.

File “extension”

There’s an R script under ./module folder named not_func.r, where objects that are non-functions are contained. Use this code and save it on not_func.r:

box::use(
    tibble[as_tibble],
    datasets[iris]
)

#' @export
pi = pi

#' @export
iris = as_tibble(iris)

#' @export
sales = readRDS(box::file('data/sales.rda'))
Note

Considering all of the assigned objects under the module namespace are exported, no need to place #' @export. Only use #' @export if you preferred to specifically export some assigned objects under the namespace of the module. When you load external packages or modules with box::use(), only what’s inside the namespace of the package to be exported.

Save that script and then try load the module:

box::use(
    ./module/not_func
)

If you have the initial file __init__.r under ./module which publicly exports not_func, you are allowed to import not_func.r as a module through the following:

box::use(
    md_dt = ./module[not_func]
)

This is a bit trickier. While this import declaration will write md_dt module environment within the current environment, containing the namespace of ./module, this will also load/attach not_func module at the same time. This was already discussed on “Granular Imports with Aliases” in Chapter 2: Array of Imports with Monikers.

Attaching an object

The granular import semantics still applies to assigned objects that are not limited to function. So, if you do the following:

box::use(
    ./module[not_func]
)

Then try access the data under not_func module like this:

not_func$pi
not_func$iris
head(not_func$mpg, 5)

If it is the other way around:

box::use(
    md_dt = ./module/not_func
)

The logic stays the same, just the syntax is a bit different:

md_dt$pi
md_dt$iris
head(md_dt$mpg, 5)

Don’t forget that specified granular imports are allowed:

box::use(
    ./module/not_func[pi, iris, sales]
)

Then access them freely in R:

pi
iris
head(sales, 5)

Just don’t forget to maintain your current environment to avoid conflicts.

And that’s how it is done. I hope you followed the steps so that you can proceed to the next part.