Loading packages at startup

Timothy H. Keitt tkeitt@mail.utexas.edu
22 Oct 2002 10:55:42 -0700

[Sorry, just noticed this thread and don't know what's been said
already, but I will comment nonetheless.]

I've also thought about this problem and I think we should be careful to
make sure its solved in a very general manner. Objects bind methods to
data, but this is broken when saving and reloading R sessions (only the
data ends up in .RData and not the bindings). What happens if someone
has multiple saved R sessions in a single directory? A single .Rpackages
file would either leave out packages or have to include all packages
across all sessions. I would far rather have a mechanism that recognizes
an object as an object and lets that object load the appropriate
bindings to methods at (re)instantiation. I once proposed that there be
function hooks in the save/load process that could be overloaded by
object type to make sure that any initializations (including package
loading) could be completed before attaching the data. This would also
allow for example database objects to reestablish their connections when
a session is reloaded from disk.


On Tue, 2002-10-22 at 06:46, Warnes, Gregory R wrote:
> > 4) One problem with saving an R session and then restoring it is that
> >    the packages in use are not reloaded.  Quitting an R session and
> >    saving could write .Rpackages in the current directory (with the
> >    library recorded if it were not the default).  Then restarting a
> >    session in that directory would restore the loaded packages
> >    automatically.
> I've been using another approach for this.   For the R + Zope tools that
> I've developed here (Yes, they will be released once I finally get through
> all the red tape!) I needed a way to store all of the information about a
> session, including loaded packages and the search path.
> At the end of this message, I list two functions, save.session() and
> load.session() which I wrote to accomplish this.  In addition, I have an .Rd
> documentation file for them, and can provide that if anyone is interested.
> The functions save.session() records the list of loaded packages into a
> variable named ".save.session.packages" which is then saved as part of
> save.image().   The load.session() function then uses load() to reload the
> saved image and uses the ".save.session.packages" function to reload the
> packages.  A similar thing happens for the search path.   This works well
> and seems less hazard-prone than overwriting the users '.Rpackages' file for
> two reasons:  1) the loaded package list and search path are preserved with
> the data, and 2) we aren't messing with the user's files...
> One enhancement that would be desirable is to allow the user to request that
> the search path or the packages not be restored.  Of course, both can be
> avoided by just using load() instead of load.session() on the data file.
> -Greg
> save.session <- function(file=".RSession",...)
>   {
>     if(!is.null(dev.list()))
>        warning("Open graphics devices will not be saved or restored.")
>     cat("Saving search path..\n")
>     .save.session.search <<- search()
>     cat("Saving list of loaded packages..\n")
>     .save.session.packages <<- .packages()
>     cat("Saving all data...\n")
>     save(list=ls(envir = .GlobalEnv, all.names = TRUE), file=file, ...)
>     cat("Done.\n")
>   }
> restore.session <- function(file=".RSession",...)
>   {
>     cat("Loading all data...\n")
>     load(file,envir = .GlobalEnv,...)
>     cat("Loading packages...\n")
>     sapply( rev(.save.session.packages), library, character.only=T )
>     cat("Restoring search path...\n")
>     pad <- function(x,n) c( rep(NA,n-length(x)), x )
>     current.search <- search()[-1]
>     saved.search <- .save.session.search[-1]
>     identical <- pad(current.search, length(saved.search)) == saved.search 
>     for( i in saved.search[!identical] )
>       {
>         if( charmatch( "file:", i, nomatch=FALSE) )
>           attach(sub( "file:", "", "file:test" ) )
>         else if (charmatch( "package:", i, nomatch=FALSE)  )
>           stop(paste("Somehow we missed loading package",i))
>         else
>           {
>             do.call("attach",list(as.name(i)))
>           }
>       }
>     rm(list=c(".save.session.packages",
>               ".save.session.search"),
>        envir = .GlobalEnv )
>     cat("Done.\n")
>   }    
> Unless expressly stated otherwise, this message is confidential and may be privileged. It is intended for the addressee(s) only. Access to this E-mail by anyone else is unauthorized. If you are not an addressee, any disclosure or copying of the contents of this E-mail or any action taken (or not taken) in reliance on it is unauthorized and may be unlawful. If you are not an addressee, please inform the sender immediately.
> -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
> r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
> Send "info", "help", or "[un]subscribe"
> (in the "body", not the subject !)  To: r-devel-request@stat.math.ethz.ch
> _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
Timothy H. Keitt
The University of Texas at Austin
Section of Integrative Biology
1 University Station C0930
Austin, Texas 78712-0253 USA
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-devel-request@stat.math.ethz.ch