Skip to content

2026

Dynamic R Library Paths - Version-Aware .Rprofile Configuration

The Problem When managing multiple R versions in an HPC environment, hardcoding library paths in your .Rprofile can quickly become a maintenance headache. Consider this common scenario:

.libPaths(c("~/devel/R/4.3/skylake/"))

This works fine—until you switch to R 4.4 or 4.5. Suddenly, you're either loading incompatible packages or manually editing your .Rprofile every time you change R modules.

The Solution: Version-Aware Library Paths

Instead of hardcoding the R version, we can make .Rprofile detect the current R version automatically and set the appropriate library path:

# Dynamically set R package location based on R version
r_version <- paste(R.version$major, 
                   strsplit(R.version$minor, "\\.")[[1]][1], 
                   sep = ".")
platform <- R.version$platform
user_lib <- path.expand(sprintf("~/devel/R/%s-library/%s/", platform, r_version))

# Check if the directory exists, if not, warn the user
if (dir.exists(user_lib)) {
  .libPaths(c(user_lib, .libPaths()))
} else {
  warning(sprintf("User library path does not exist: %s", user_lib))
  # Optionally, create it automatically:
  # dir.create(user_lib, recursive = TRUE, showWarnings = FALSE)
}

How It Works

  • Extract the version: R.version$major and R.version$minor give us the version components
  • Parse major.minor: We extract just "4.3", "4.4", or "4.5" (not the full minor version like "4.3.2")
  • Get the platform: R.version$platform provides the architecture string (e.g., x86_64-pc-linux-gnu)
  • Construct the path: Using sprintf() to build the path dynamically
  • Prepend to library paths: Using .libPaths(c(user_lib, .libPaths())) ensures your user library takes precedence while keeping system libraries as fallback

Complete .Rprofile Example

# Dynamically set R package location based on R version and platform
r_version <- paste(R.version$major, 
                   strsplit(R.version$minor, "\\.")[[1]][1], 
                   sep = ".")
platform <- R.version$platform
user_lib <- path.expand(sprintf("~/devel/R/%s-library/%s/", platform, r_version))

if (!dir.exists(user_lib)) {
  message(sprintf("Creating user library: %s", user_lib))
  dir.create(user_lib, recursive = TRUE, showWarnings = FALSE)
}
.libPaths(c(user_lib, .libPaths()))

# Set a local mirror for packages
options(repos = structure(c(CRAN = "https://www.stats.bris.ac.uk/R/")))

# Set cairo as the default bitmap type
options(bitmapType = 'cairo')

Alternative: Explicit Version Checking

If you need more granular control or want to handle specific versions differently:

# Get R version and platform
r_version <- getRversion()
platform <- R.version$platform

if (r_version >= "4.5.0") {
  user_lib <- path.expand(sprintf("~/devel/R/%s-library/4.5/", platform))
} else if (r_version >= "4.4.0") {
  user_lib <- path.expand(sprintf("~/devel/R/%s-library/4.4/", platform))
} else if (r_version >= "4.3.0") {
  user_lib <- path.expand(sprintf("~/devel/R/%s-library/4.3/", platform))
} else {
  user_lib <- NULL
}

if (!is.null(user_lib) && dir.exists(user_lib)) {
  .libPaths(c(user_lib, .libPaths()))
}

This approach is useful if different R versions need different handling or if you're maintaining legacy versions with special requirements.

Tips

Create library directories in advance: Set up your directory structure before installing packages:

mkdir -p ~/devel/R/x86_64-pc-linux-gnu-library/{4.3,4.4,4.5}
  • Verify your platform string: Check what R reports:
R.version$platform
# [1] "x86_64-pc-linux-gnu"

Test after changes: After modifying .Rprofile, start a new R session and verify:

.libPaths()
# Should show your user library first, then system libraries