4

I would like to used delayedAssign to load a series of data from a set of files only when the data is needed. But since these files will always be in the same directory (which may be moved around), instead of hard coding the location of each file (which would be tedious to change later on if the directory was moved), I would like to simply make a function that accepts the filepath for the directory.

loadLayers <- function(filepath) {

  delayedAssign("dataset1", readRDS(file.path(filepath, "experiment1.rds")))  
  delayedAssign("dataset2", readRDS(file.path(filepath, "experiment2.rds"))) 
  delayedAssign("dataset3", readRDS(file.path(filepath,"experiment3.rds"))) 
  return (list <- (setOne = dataset1, setTwo = dataset2, setThree = dataset3)
}

So instead of loading all the data sets at the start, I'd like to have each data set loaded only when needed (which speeds up the shiny app).

However, I'm having trouble when doing this in a function. It works when the delayedAssign is not in a function, but when I put them in a function, all the objects in the list simply return null, and the "promise" to evaluate them when needed doesn't seem to be fulfilled.

What would be the correct way to achieve this? Thanks.

ruisen
  • 305
  • 3
  • 11

1 Answers1

7

Your example code doesn't work in R, but even conceptually, you're using delayedAssign and then you immediately resolve it by referencing it in return() so you end up loading everything anyway. To make it clear, assignments are binding a symbol to a value in an enviroment. So in order for it to make any sense your function must return the environment, not a list. Or, you can simply use the global environment and the function doesn't need to return anything as you use it for its side-effect.

loadLayers <- function(filepath, where=.GlobalEnv) {
  delayedAssign("dataset1", readRDS(file.path(filepath, "experiment1.rds")),
                assign.env=where)
  delayedAssign("dataset2", readRDS(file.path(filepath, "experiment2.rds")),
                assign.env=where) 
  delayedAssign("dataset3", readRDS(file.path(filepath, "experiment3.rds")),
                assign.env=where)
  where
}
Simon Urbanek
  • 13,842
  • 45
  • 45
  • If I'm not using the global environment, but the environment where loadLayers() is called, if I need to access dataset1, can I just directly use dataset1, or do I need to use envir_name$dataset1, where envir_name is the environment that calls loadLayers? – ruisen Feb 05 '16 at 21:29