# How to Use renv for Reproducible R Environments in Bioinformatics

By the end of this article you will be able to set up renv in an R for bioinformatics project, record the exact versions of every package you use (including Bioconductor packages such as DESeq2), restore that environment on a collaborator's laptop or a compute cluster, and connect the renv layer to a larger workflow system. You will also be able to diagnose the package installation errors that show up most often in genomics work.

You need on hand:

- A current release of R installed (4.x series). Check with `R.version.string` in the console.
- Write access to the project folder where your analysis lives.
- Git for version control, strongly recommended, because the renv lockfile belongs in your repository.
- For Bioconductor work, `BiocManager`, which you will install in the walkthrough.
- On a cluster, a module system or a preinstalled R binary. Nothing else is required, because renv manages packages, not R itself.

## Why R Environments Drift in Bioinformatics

Bioinformatics pipelines chain many software steps, and each step can fail or change independently. The H3ABioNet consortium, which built variant calling, 16S, genotyping, and imputation workflows across institutions in 17 African countries, described how hard it is to implement workflows that are scalable, reproducible, and portable across heterogeneous computing environments [1]. That problem does not disappear when a step happens to be written in R.

R makes the problem sharper for two reasons.

First, R packages change constantly. CRAN, the Comprehensive R Archive Network, only keeps the latest version of each package available. When a package author pushes an update, yesterday's documented behavior can silently change. A genomics workflow built around R scripts can lose reproducibility this way. Winkler coined the term "workflow decay" for exactly this effect, where analyses become hard to reproduce because the computing platform underneath them drifts, and argued for a standardized informatic infrastructure to slow that decay [2].

Second, most bioinformatics analysis in R leans on Bioconductor, the project that curates genomics packages such as DESeq2, limma, GenomicRanges, and methylKit. Bioconductor follows a twice-yearly release cycle, so the set of package versions you get depends heavily on when you installed them. A recent best-practices protocol for targeted methylation sequencing analysis, for example, embeds a downstream statistical stage in R that performs beta-value calculation, differential methylation with methylKit, PCA, and regional profiling, and treats explicit, harmonized reporting of that stage as part of reproducibility [3]. That R stage is only reproducible if the package versions behind methylKit are pinned.

A review of pipeline development makes the boundary clear. Scripting languages like Python, R, and notebooks are popular and sufficient for small-scale pipelines intended for a single user, but they are not enough on their own for large-scale, shareable, maintainable, and reusable pipelines [4]. renv is the piece that fixes the R package layer. Other pieces, covered later in this article, handle workflow orchestration and system dependencies.

## How renv Works: Library, Lockfile, Cache

renv is an R package that gives each project its own private package library and records its state in a lockfile. Three concepts matter.

**Project library.** Normally, `install.packages()` puts packages in one user-level or system-wide library shared by every project. With renv, each project gets its own `renv/library` folder. Installing DESeq2 version X in one project does not touch another project.

**Lockfile.** `renv.lock` is a JSON file that records the R version, the package repositories (including the Bioconductor version), and every package with its exact version and a hash of its DESCRIPTION metadata. A hash is a short fingerprint computed from the package's metadata, and renv uses it to detect whether a package has actually changed.

**Global cache.** To avoid reinstalling the same package 20 times across 20 projects, renv stores each package version once in a central cache on your machine and links it into each project library. This is why renv projects start up quickly after the first install.

Two verbs tie it together. `renv::snapshot()` writes the current state of your project library into `renv.lock`. `renv::restore()` rebuilds the project library from `renv.lock`. Snapshot and restore are the whole game in renv r reproducibility bioinformatics: snapshot after you change the environment, restore to reproduce it elsewhere.

## Step-by-Step: renv in a Genomics Project

This walkthrough uses a realistic [RNA-seq differential expression](/knowledge/bioinformatics/rna-seq-differential-expression-deseq2-edger) project. Substitute your own packages. The commands are identical for a methylation analysis with methylKit or any other Bioconductor-centered analysis.

### 1. Install renv

Open R in your project directory (or open the project in RStudio) and run:

```r
install.packages("renv")
packageVersion("renv")
```

You should see a recent version number printed, for example ` '1.0.0'`. If you are on a managed cluster and `install.packages()` fails with a permission error, install into a personal library:

```r
dir.create("~/R/library", recursive = TRUE)
install.packages("renv", lib = "~/R/library")
.libPaths(c("~/R/library", .libPaths()))
```

### 2. Initialize the project

```r
renv::init()
```

Representative output:

```
* Discovering project dependencies ... Done!
* Copying packages into the project library ...
* Project "~/projects/rnaseq-de " loaded. [renv 1.0.0]
```

renv does four things here:

- Creates `renv/` containing an activation script and settings.
- Creates a private project library.
- Writes `.Rprofile` in the project so that opening the project automatically activates renv.
- Writes an initial `renv.lock` and, if it finds packages already in use, records them.

It also adds the project library paths to `.gitignore`. The lockfile `renv.lock` should be committed to Git. The `renv/library` folder should never be committed, because it is rebuilt from the lockfile by anyone who clones the repository.

### 3. Install packages the renv way

For a typical differential expression analysis you might need:

```r
renv::install("bioc::DESeq2")
renv::install("bioc::tximport")
renv::install("ggplot2")
renv::install("pheatmap")
```

The `renv::install()` function installs into the project library and registers the package with renv. The `bioc::` prefix tells renv to pull the package from Bioconductor. You can also use plain GitHub notation for development versions:

```r
renv::install("rstudio/renv")
```

If you prefer to keep using `install.packages()` and `BiocManager::install()` out of habit, renv will notice packages that appear in the project library without being recorded, but calling `renv::install()` directly avoids one whole class of "installed but not recorded" problems described later.

### 4. Snapshot the environment

```r
renv::snapshot()
```

Representative output:

```
The following package(s) will be updated in the lockfile:

# CRAN ===============================
- ggplot2   [* -> 3.5.1]
- pheatmap  [* -> 1.0.12]

# Bioconductor =======================
- DESeq2    [* -> 1.44.0]
- tximport  [* -> 1.30.0]

Do you want to proceed? [y/N]:
```

The versions shown here are illustrative. Your lockfile will contain whatever versions you actually installed. After confirming, open `renv.lock` and inspect it. A truncated entry looks like this:

```json
{
  "R": {
    "Version": "4.4.1",
    "Repositories": [
      { "Name": "CRAN", "URL": "https://cloud.r-project.org" }
    ]
  },
  "Packages": {
    "DESeq2": {
      "Package": "DESeq2",
      "Version": "1.44.0",
      "Source": "Repository",
      "Repository": "Bioconductor",
      "Hash": "..." 
    }
  }
}
```

Three fields do the reproducibility work. `Version` pins the package. `Repository` says where renv must fetch it. `Hash` lets renv verify that the package it finds today is metadata-identical to the one you used. Commit this file:

```bash
git add renv.lock .Rprofile renv/ .gitignore
git commit -m "Pin renv environment for DE analysis"
```

### 5. Restore the environment somewhere else

On a collaborator's machine, or your own after a reinstall, clone the repository and start R inside the project. renv activates automatically and tells you the library is empty or out of date. Run:

```r
renv::restore()
```

Representative output:

```
- Installing DESeq2 ... OK [installed from Bioconductor]
- Installing tximport ... OK [installed from Bioconductor]
- Installing ggplot2 ... OK [downloaded from CRAN]
- 1 restored package in 0.42 seconds
```

Two things can make this fast. If the collaborator's global cache already holds the exact package version, renv links it in within seconds. If not, renv downloads and compiles each package, which for a heavy Bioconductor stack can take from tens of minutes to an hour or more on a laptop.

### 6. Adopt the daily loop

![Four-step loop: install with renv, run the analysis, check status, then snapshot and commit the lockfile.](/article-images/illustrations/renv-r-reproducibility-bioinformatics-daily-loop.webp)

The working pattern for renv r reproducibility bioinformatics is short:

1. Install or update a package with `renv::install()`.
2. Run your analysis.
3. Run `renv::status()`.
4. If renv reports the lockfile is out of sync, run `renv::snapshot()` and commit.

```r
renv::status()
```

Healthy output ends with:

```
* The R package repository is synchronized with the lockfile.
```

Anything else means your project library and `renv.lock` disagree, and you should resolve it before committing.

## Managing Bioconductor Packages with renv

Bioconductor deserves its own section because most R for bioinformatics projects live or die on it, and because Bioconductor behaves differently from CRAN in ways that matter to renv.

**Bioconductor releases are versioned and biannual.** The Bioconductor release is tied to a specific R minor version. Mixing packages from different Bioconductor releases in one library is unsupported and a frequent source of obscure errors. Check your release with:

```r
BiocManager::version()
BiocManager::valid()
```

`BiocManager::valid()` verifies that your installed Bioconductor packages are current and mutually compatible. Run it after a restore to confirm the environment is internally consistent.

**renv records the Bioconductor state in the lockfile.** Alongside the R version and CRAN repositories, `renv.lock` captures the Bioconductor version in use, so a restore on another machine targets the same release rather than whatever is current that week. This is the difference between "I installed methylKit" and "I installed the methylKit version from Bioconductor release 3.x that shipped with the R version in my lockfile," and it is the difference that makes a methylation R stage reproducible rather than approximately similar [3].

**Use the bioc shortcut and keep system libraries ready.** Many Bioconductor packages wrap C libraries. Packages in the Rsamtools and rtracklayer families need zlib, libbz2, liblzma, and libcurl at compile time, and XML or rxml-based packages need libxml2. If the underlying system library is absent, you will see a configure error, not an R error. The fix lives at the operating system level (install the development headers with your package manager, or request the module from your cluster administrator), not inside renv. This is a recurring theme: renv pins the R layer, and you must arrange the layers below it.

**Package ecosystems built around S4 containers restore cleanly.** Modern omics packages organize data in formal S4 classes, which are R's structured object system. A package like MeTime, which wraps longitudinal metabolomics methods inside a central S4 container and retains intermediate results and provenance for reproducible HTML and PDF reporting, depends on a deep chain of Bioconductor infrastructure [5]. That chain is exactly what the lockfile pins, so snapshotting such a project captures far more than the top-level package name.

## renv on Shared Clusters and HPC

The heterogeneous-environment problem H3ABioNet documented, where the same workflow must run across many institutions with different computing setups, is the daily reality of a shared cluster [1]. Practical renv r reproducibility bioinformatics tips for clusters:

**Load R through the module system before initializing.** renv does not install R. On a cluster:

```bash
module load R/4.4.1
Rscript -e "renv::init()"
```

Record in your README which module or container provided the R binary, because the lockfile alone does not carry that information.

**Point the cache at shared storage when it helps.** The global cache lives under a user-specific path by default, controlled by the `RENV_PATHS_ROOT` environment variable. On a lab server where several people run the same project, you can set `RENV_PATHS_ROOT` to a shared location in your `.Renviron` so that restored packages are reused across users instead of recompiled per person:

```r
# ~/.Renviron on a shared server
RENV_PATHS_ROOT=/shared/renv-cache
```

Agree on who can write there. A cache directory with mixed write permissions is a common source of "permission denied" failures during restore.

**Use noninteractive settings for scheduled jobs.** renv asks for consent before using the cache by default, which hangs batch jobs. Set it once:

```r
renv::consent(provide = TRUE)
```

and in scripts call restore with quiet, explicit flags so a cron or Slurm job never waits on a prompt.

**Expect first-restore time to be the main cost.** Every user and every node can share the cache, so after one person restores the environment, everyone else links against it. Budget an hour for the very first restore of a full Bioconductor stack, and plan that as a one-time setup step rather than something that happens on every job.

## renv Next to Workflow Managers and Containers

![Comparison table showing renv, a container and a workflow engine each covering different parts of the reproducibility stack.](/article-images/illustrations/renv-r-reproducibility-bioinformatics-layer-scope.webp)

renv solves one layer. Where does it sit relative to Nextflow, Snakemake, or Galaxy?

The modern pattern, visible in published workflows, is to separate concerns. The tcga-data-nf workflow reproduces regulatory network inference over thousands of TCGA samples with a single Nextflow command, and it delegates the R-specific [data management](/blog/guides/data-management-basics-principles-processes-and-best-practices) to a standalone companion package, NetworkDataCompanion [6]. The workflow engine handles orchestration, containers, and data provenance. The R package layer inside each process is where renv belongs.

The same division appears in Galaxy-based systems. GCAC wraps an R statistical pipeline for predictive model building in virtual screening, using the R environment plus literate programming tools inside Galaxy to guarantee reproducibility [7]. If you wrapped R scripts in Galaxy today, renv would sit inside the tool definition, pinning the R packages while Galaxy handles execution and history.

A review of pipeline reuse practice concludes that scientific workflow systems provide modularity, reproducibility, and reusability that scripting alone cannot deliver at scale [4]. Take that as guidance about scope, not as a reason to skip renv. The practical stack for a serious project is:

1. renv pins the R and Bioconductor package versions inside each R step.
2. A workflow engine (Nextflow, Snakemake, Galaxy) chains steps and handles data movement.
3. A container image (Docker or Apptainer) pins the operating system, R binary, and system libraries.
4. Git pins your code and `renv.lock`.

One caveat from long-running modeling work. QSP model development is iterative and evolutive, and the available modeling tools and techniques vary widely across problems [8]. Your environment will change over the life of a project. That is fine. Snapshot on every meaningful change and commit the lockfile alongside the code it supports, and your Git history becomes a timeline of environments, one per commit, any of which you can restore.

## Checking That Your Environment Is Actually Reproducible

A lockfile you never tested is a hope, not a result. Verify with this sequence:

```r
# 1. Sync check
renv::status()

# 2. Bioconductor consistency
BiocManager::valid()

# 3. Find every package your scripts actually reference
renv::dependencies()

# 4. Record the session for your report
sessionInfo()
```

`renv::dependencies()` scans your R and R Markdown files for package calls and reports packages used but not recorded in the lockfile. This catches packages you loaded interactively and forgot to snapshot.

Then do the decisive test. In a scratch directory, clone the repository and run `renv::restore()` with your usual cache path temporarily moved aside (set `RENV_PATHS_ROOT` to an empty directory). If the project installs and your pipeline runs end to end, your lockfile is real. This exercise also gives you an honest time estimate for onboarding a new collaborator.

Finally, put `sessionInfo()` output, or the rendered version from a Quarto or R Markdown report, into your results folder and your repository. It documents the R version and package versions that produced a given figure, complementing the lockfile with a human-readable record.

## Key renv Commands and Options

| Task | Command | Notes |
|--|--|--|
| Start renv in a project | `renv::init()` | Creates project library, `.Rprofile`, and first lockfile |
| Install from CRAN | `renv::install("ggplot2")` | Installs into the project library and records it |
| Install from Bioconductor | `renv::install("bioc::DESeq2")` | Requires `BiocManager` to be available |
| Install from GitHub | `renv::install("owner/repo")` | Pins the commit it installs from |
| Record current state | `renv::snapshot()` | Writes `renv.lock`. Commit it afterward |
| Snapshot every library package | `renv::snapshot(type = "all")` | Captures packages even if no script references them |
| Rebuild from lockfile | `renv::restore()` | Target of collaborators, CI, and fresh machines |
| Check sync | `renv::status()` | Lists installed-but-unrecorded and recorded-but-uninstalled packages |
| Remove a package | `renv::remove("pkg")` | Removes from the library, then snapshot |
| Find packages used by scripts | `renv::dependencies()` | Static scan of project files |
| Move cache root | `RENV_PATHS_ROOT` | Set in `.Renviron` for shared or redirected caches |
| Skip interactive prompts | `renv::consent(provide = TRUE)` | Required for noninteractive cluster jobs |

## Common Errors and Fixes

**"Error in library(DESeq2) : there is no package called 'DESeq2'".** The package is not installed in the active project library. Run `renv::status()` to see whether it is recorded in the lockfile. If recorded, run `renv::restore()`. If not recorded, run `renv::install("bioc::DESeq2")` and then `renv::snapshot()`.

**"there is no package called 'BiocManager'".** renv needs `BiocManager` to resolve Bioconductor packages, and a fresh restore environment may not include it. Install it with `renv::install("bioc::BiocManager")` and re-run restore. Consider recording it in the lockfile of every Bioconductor project.

**Configure errors mentioning curl, xml2, or zlib.** A typical transcript contains lines like `checking for curl...` followed by `configure: error:` and then `ERROR: configuration failed for package 'curl'`. This is a missing C library, not an R problem. On Ubuntu, install `libcurl4-openssl-dev`, `libxml2-dev`, `libssl-dev`, and `zlib1g-dev`. On macOS with Homebrew, install the corresponding formulae. On a cluster, ask your administrator for the matching module or install these libraries into your own prefix and point the build at it.

**"package 'X' is not available" during restore.** Either the version in your lockfile has been archived on CRAN or the repository mirror lacks it. Options in order of preference: use `renv::install("pkg@1.2.3")` to install a specific archived version and snapshot, point your repositories at a CRAN snapshot service that serves packages by date, or place the source tarball in the project and install it locally. Whichever route you take, snapshot so the resolution is recorded.

**renv::status reports "The following package(s) are installed but not recorded in the lockfile".** You (or a stray `install.packages()` call) added packages that the lockfile does not know about. Decide whether to keep them, in which case run `renv::snapshot()`, or drop them with `renv::remove()` followed by `renv::snapshot()`.

**renv::status reports "The following package(s) are recorded in the lockfile but not installed".** Something deleted packages from the project library, often a manual library wipe or a cluster scratch purge. Run `renv::restore()` to bring the library back to the committed state.

**Permission denied during restore on a shared system.** The global cache is owned by another user, or your group lacks write access to `RENV_PATHS_ROOT`. Either fix the group permissions on the shared cache or fall back to a personal cache path.

## Common Mistakes and Limitations

- **Committing `renv/library` to Git.** It is large, binary-heavy, and platform-specific. Commit `renv.lock` and the `renv/` infrastructure, and let collaborators run `renv::restore()`. renv's own `.gitignore` entries exist for this reason, and deleting them causes pain.
- **Treating the lockfile as a full system snapshot.** renv pins R packages. It does not pin the R interpreter, the operating system, compilers, zlib, libcurl, or command-line tools like samtools or FastQC. The methylation workflow protocol cited earlier coordinates R tools with Trim Galore, FastQC, BWA-meth, and Picard in a single pipeline [3]. renv covers only the R corner of that stack. Pair renv with a container for the rest.
- **Relying on implicit snapshots with dynamically loaded packages.** By default, renv snapshots packages it can detect as used in your project files. Bioinformatics code often loads packages from a character vector read out of a config file, or uses `::` inside functions constructed at runtime, and those references are invisible to a static scan. Use `renv::snapshot(type = "all")` in such projects, or add an explicit `renv::record()` line for packages the scanner cannot see.
- **Ignoring the R version field.** The lockfile records the R version but cannot install it. Restoring a lockfile built under R 4.4 onto an R 4.1 install can fail on packages that require newer R. Standardize the R version across your team, ideally through the same container or module.
- **Assuming the cache solves compile problems.** The cache avoids recompilation only when the exact package version already exists in it. A new machine with a different operating system or compiler still compiles from source, and still needs the system headers described above.
- **Letting the lockfile go stale.** The most common failure in renv r reproducibility bioinformatics is a team that installs packages for weeks without running `renv::status()` or committing snapshots. The lockfile then describes a fantasy environment. Make snapshot-and-commit part of the same reflex as commit-and-push.
- **Expecting renv to manage data.** Input FASTQ files, reference genomes, and annotation versions are outside renv's scope. Pipeline papers that achieve end-to-end reproducibility, such as the TCGA workflow with its data download and [preprocessing](/blog/data-analysis/what-is-data-preprocessing) stages under one command [6], achieve it by versioning data and parameters at the workflow layer. Your README should record reference genome builds and annotation releases next to the lockfile.

## Frequently Asked Questions

### Does renv lock the R version itself?

No. renv records the R version in `renv.lock` but cannot install R. You must supply a matching R installation yourself, usually through the same module, container, or installer across your team. Check the recorded version against `R.version.string` when a restore misbehaves.

### Can renv capture Bioconductor packages?

Yes. renv records Bioconductor packages and the Bioconductor release in the lockfile. Install with `renv::install("bioc::PackageName")`, snapshot as usual, and run `BiocManager::valid()` after a restore to confirm internal consistency.

### How is renv different from conda or packrat?

renv manages R package libraries and a lockfile per project, on top of whatever R you have. Conda manages R itself plus system libraries and non-R tools in an environment. packrat is renv's predecessor with the same core idea but no shared cache and slower installs. Many bioinformatics teams use conda or a container for the system layer and renv for the R package layer.

### Should I commit renv.lock and the renv folder to Git?

Commit `renv.lock` and the small `renv/` infrastructure files including `.Rprofile`. Do not commit `renv/library`, which renv adds to `.gitignore` by default. Collaborators rebuild the library from the lockfile with `renv::restore()`.

### How do I restore a project on a cluster with no internet access?

Restore on a machine with internet first so the shared cache or your personal cache fills up, then set `RENV_PATHS_ROOT` on the offline system to a location containing that populated cache, and run `renv::restore()`. renv links packages from the cache without downloading when the exact versions are present.

### What if a locked package version is no longer on CRAN?

CRAN keeps only current versions, so an archived version must come from the CRAN archive, a dated CRAN snapshot service, or a local tarball. Install the specific version with `renv::install("pkg@version")`, confirm your analysis still runs, and snapshot so the resolution sticks.

### Does renv slow down package installation?

The first install is comparable to a normal install, and the first restore of a full Bioconductor stack can take an hour on a laptop. After that, the shared cache makes installs and restores of already-cached versions nearly instant, so most day-to-day renv work is faster than reinstalling into a shared library.

### Can I use renv with R Markdown or Quarto reports?

Yes, and you should. renv detects package references in R Markdown and Quarto files during dependency scanning. Render your report inside the renv project so the figures are generated by the pinned package versions, and include `sessionInfo()` output with the report for a readable record of the environment that produced it.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Does renv lock the R version itself?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "No. renv records the R version in renv.lock but cannot install R. You must supply a matching R installation yourself, usually through the same module, container, or installer across your team."
      }
    },
    {
      "@type": "Question",
      "name": "Can renv capture Bioconductor packages?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Yes. renv records Bioconductor packages and the Bioconductor release in the lockfile. Install with renv::install(\"bioc::PackageName\"), snapshot as usual, and run BiocManager::valid() after a restore to confirm consistency."
      }
    },
    {
      "@type": "Question",
      "name": "How is renv different from conda or packrat?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "renv manages R package libraries and a lockfile per project on top of whatever R you have. Conda manages R itself plus system libraries and non-R tools. Packrat is renv's predecessor without the shared cache. Many teams pair a container or conda for the system layer with renv for the R package layer."
      }
    },
    {
      "@type": "Question",
      "name": "Should I commit renv.lock and the renv folder to Git?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Commit renv.lock and the small renv infrastructure files including .Rprofile. Do not commit renv/library, which renv adds to .gitignore by default. Collaborators rebuild the library with renv::restore()."
      }
    },
    {
      "@type": "Question",
      "name": "How do I restore a project on a cluster with no internet access?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Restore on a machine with internet first so the renv cache fills, then set RENV_PATHS_ROOT on the offline system to that populated cache and run renv::restore(). renv links packages from the cache without downloading when the exact versions are present."
      }
    },
    {
      "@type": "Question",
      "name": "What if a locked package version is no longer on CRAN?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "CRAN keeps only current versions. Install the archived version with renv::install(\"pkg@version\"), use a dated CRAN snapshot service, or install from a local tarball, then snapshot so the resolution is recorded."
      }
    },
    {
      "@type": "Question",
      "name": "Does renv slow down package installation?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "The first install and restore of a full Bioconductor stack can take an hour on a laptop. After that, the shared cache makes installs and restores of cached versions nearly instant, so most day-to-day renv work is faster than reinstalling into a shared library."
      }
    },
    {
      "@type": "Question",
      "name": "Can I use renv with R Markdown or Quarto reports?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Yes. renv detects package references in R Markdown and Quarto files during dependency scanning. Render your report inside the renv project so figures are produced by the pinned versions, and include sessionInfo() output with the report."
      }
    }
  ]
}
</script>

## Sources

1. [Developing reproducible bioinformatics analysis workflows for heterogeneous computing environments to support African genomics.](https://pubmed.ncbi.nlm.nih.gov/30486782/)
2. [An evolving computational platform for biological mass spectrometry: workflows, statistics and data mining with MASSyPup64.](https://pubmed.ncbi.nlm.nih.gov/26618079/)
3. [A Guide to Enzymatic Targeted Methylation Sequencing Bioinformatics Workflow: Best Practices.](https://pubmed.ncbi.nlm.nih.gov/42848382/)
4. [Developing and reusing bioinformatics data analysis pipelines using scientific workflow systems.](https://pubmed.ncbi.nlm.nih.gov/36968012/)
5. [MeTime: an R package for reproducible longitudinal metabolomics data analysis.](https://pubmed.ncbi.nlm.nih.gov/42730207/)
6. [Reproducible processing of TCGA regulatory networks.](https://pubmed.ncbi.nlm.nih.gov/41114645/)
7. [GCAC: galaxy workflow system for predictive model building for virtual screening.](https://pubmed.ncbi.nlm.nih.gov/30717669/)
8. [Quantitative Systems Pharmacology: An Exemplar Model-Building Workflow With Applications in Cardiovascular, Metabolic, and Oncology Drug Development.](https://pubmed.ncbi.nlm.nih.gov/31087533/)