knitr::opts_chunk$set( collapse=TRUE, warning=FALSE, message=FALSE, comment="#>", fig.path="man/figures/README-" ); options(knitr.table.format='markdown')
The goal of jamsession is to help manage
refresh_functions("project")
Functions are loaded inside a temporary R package, separate from your R workspace.
save_object("some_fancy_object")
load_object("some_fancy_object")
Objects are loaded into the user environment, but can be loaded into a separate environment if needed.
save_jamsession("myproject")
load_jamsession("myproject")
The full R session and R history is loaded (if available) into the user workspace. It can be loaded into a separate environment if needed, in which case the history is not loaded.
# install.packages(remotes) remotes::install_github("jmw86069/jamsession")
Have you ever been asked a follow-up question about your R analysis results?
.RData
file?Do you sometimes create useful R data objects that you later re-use in other R analysis projects?
Do you create and modify custom functions for your projects, before they may (or may not) become part of an R package?
My answers are YES, YES, YES! (And YES for each of the sub-questions.)
roxygen2
.A full online function reference is available via the pkgdown documentation:
Full jamsession command reference
For me, it is routine to get asked follow-up questions, sometimes a year or more after the original analysis. Sometimes a manuscript reviewer asked us to re-cluster data with different distance metric; or make the font size larger on a figure; or try a new method on the results...
I need a rapid way to re-load a past R session, with all the supporting R objects in that session, so I can continue work right where I left off.
First time analyzing data for a new project...
library(jamsession); ## Some analysis work lotty_dah <- data.frame(A=1:10, B=LETTERS[1:10]); ## Save the project at the end save_jamsession("LottyDah");
Deliver results to Dr. Dah, who is very excited, reviews results for a few weeks, then responds, "Hey what about C?" Meanwhile, I've been working on other projects, but I can answer with confidence: "Sure thing, let me just load the project and look into C."
## Look for Lotty's project grep_jamsessions("Lotty"); #> "LottyDah" load_jamsession("LottyDah"); ## booyah lotty_dah$C <- letters[1:10]; ## Save the updated project save_jamsession();
Dr. Lotty Dah I'm sure is thinking: "Wow that was fast, thanks so much!"
I also very often create very useful reference data, that is not easy to save in a text file.
For example, Bioconductor package GenomicRanges
defines
an object GenomicRangesList
that can store gene exons, genomic
coordiantes, and associated annotations at the gene, and
gene-exon level. It takes non-trivial time to build a
proper data object, and is not easily stored in a text file.
(Ask a Bioinformatician about GTF and GFF3 files...)
Once the data is built, I really just want to save the R object directly, and re-use it in subsequent R sessions. I do this a lot.
The code below is not evaluated, but used as an example.
## Load Bioconductor package GenomicFeatures library(GenomicFeatures) ## This step takes a few minutes txdb_hg19_v32 <- GenomicFeatures::makeTxDbFromGFF("Gencode_hg19_v32.gtf") ## This step may also take a few minutes exonsByGene_hg19_v32 <- GenomicFeatures::exonsBy(txdb_hg19_v32, by="gene") ## Add gene_id to each exon values(exonsByGene_hg19_v32@unlistData)$gene_id <- rep(names(exonsByGene_hg19_v32), lengths(exonsByGene_hg19_v32)); ## Some more fancy annotation stuff ## Whoa finally, save this result! save_object("exonsByGene_hg19_v32");
For another project, I confidently say to myself: "Hey let me just re-use that cool gene-exon data I spent the time to make. Hmm... What did I call that?"
## Let me look for exonsByGene grep_objects("exonsByGene"); #> "exonsByGene_hg19_v27" #> "exonsByGene_hg19_v28" #> "exonsByGene_hg19_v32" #> "exonsByGene_mm10_vM17" #> "exonsByGene_mm10_vM24" ## Oh yeah I need hg19 version 32 load_object("exonsByGene_hg19_v32"); ## Data is loaded in a few seconds
Like many R analysts, I realize that a custom R function can make a lot of workflows much cleaner and more consistent. For a complex series of steps, I usually create an R function to perform those steps, then call the R function each time it's needed.
Sadly, I never create the perfect function the first time. I usually add features as they occur to me, or as I notice the many bugs in that function. (The majority of my code seems to be error-checking.) So I need a fast, reliable way to update the R function, refresh in my environment, then try again.
I create a file,
"myproject_functions.R"
, and a custom functionmydim()
to that file.
Note that for this example, I save the file in tempdir()
,
then I point that path with argument functions_path=tempdir()
.
For routine use, functions_path
is already defined, and I
save all my R functions to one known file path.
## Create custom function mydim <- function(x){dim(x)} ## Save it to a file fn_file <- file.path(tempdir(), "myproject_functions.R"); dump(c("mydim"), file=fn_file); rm(mydim); ## Now I can refresh_functions() to load that file refresh_functions("myproject", functions_path=tempdir());
Now what's nice is that you can see the package using
search()
, and usefind()
to find the function to confirm.
## See "myproject" as one of the packages print(search()) ## use find() to locate mydim() find("mydim") ## Run the function mydim(10); ## OOPS I forgot dim() doesn't work on vectors...
Oops, I realize
mydim()
should handlevector
different thandata.frame
. So I edit"myproject_functions.R"
and edit themydim()
function.
mydim <- function(x){adim <- dim(x);if (length(adim) == 0) {length(x)} else {adim}} fn_file <- file.path(tempdir(), "myproject_functions.R"); dump(c("mydim"), file=fn_file); rm(mydim); refresh_functions("myproject", functions_path=tempdir()); mydim(10); mydim(matrix(1:4, ncol=2))
There are other convenient benefits. If you include
roxygen2
help documentation for your function, it can be accessed with? mydim
What if you rename the function? Not a problem, the package is reloaded and the previous function name is no longer present.
mysize <- function(x){adim <- dim(x);if (length(adim) == 0) {length(x)} else {adim}} dump(c("mysize"), file=fn_file); rm(mysize); refresh_functions("myproject", functions_path=tempdir()); find("mydim"); find("mysize");
Notice that mydim()
is no longer found, but mysize()
is found.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.