Saving external data in a loop with usethis::use_data

I would like to save data to .rda files in /data.

My approach is to first set up a loop that sources R files in /data-raw while saving the result to an environment. Then I would like to save every object in the environment to and .rda file in /data using usethis::use_data().

Since use_data() calls save(), each object needs to be specified passed using its bare-unquoted name. I like to think there is a way around this using assign() and eapply(), but I am unfamiliar with looping through environments.

My work so far:

# General workflow

# All external data are read/tidied in files preceded with "external",
# and they only return that single object (one per file).

# This how I would like to create and save my external data.
external_files <- list.files("data-raw", pattern = "^external", full.names = TRUE)
external_env <- new.env()
lapply(external_files, source, local = external_env)

# Now for the hard part.
# For reproducibility I'll add something to external_env
external_env$a <- letters
external_env$i <- iris
eapply(external_env, function(x) assign(x, x, pos = .GlobalEnv))
#> Error in assign(x, x, pos = .GlobalEnv) : invalid first argument

Oddly enough, a is saved into the global environment. Data.frames/lists seem like they are unable to be saved.

Any suggestions?

2 Likes

@seasmith While it's true that use_data() requires bare-unquoted names, save() actually accepts either. Thus one option would be to use a modified version of the use_data() code that directly reads the objects in an environment and saves each one of them:

external_env <- new.env()
external_env$a <- letters
external_env$i <- iris

library(fs)
library(usethis)
path <- proj_get()
dir_data <- path(path, "data")
dir_create(dir_data)
objs <- ls(envir = external_env)
paths <- path(dir_data, objs, ext = "rda")
mapply(
  save,
  list = objs,
  file = paths,
  MoreArgs = list(envir = external_env, compress = "bzip2", version = 2)
)
2 Likes