R's library() Function Dissected

Christopher Peters · R Internals

What Does library() Do in R?

library() loads and attaches an installed R package to your current session. When you call library(dplyr), R resolves the package's install path, checks its version compatibility, loads the namespace (making all exported functions available), and checks for naming conflicts with already-loaded packages. It is the most commonly called function in R.

What library() Does Internally
Step What Happens
1. Path resolution Finds the package via .libPaths(), filters non-existent directories
2. Version check Calls testRversion() to verify the package was built for the current R version
3. License check Validates the package license via checkLicense()
4. Namespace loading Loads and attaches the namespace, making exported functions available
5. Conflict detection checkConflicts() warns if function names mask those from other packages
library() vs require(): library() throws an error if the package isn't installed; require() returns FALSE silently. Use library() in scripts (fail fast) and require() in functions where you handle the missing-package case yourself.

Source Code Walkthrough

library(): possibly the most common function call in R. What does it do? This is a dissection of the prolific function. For reference, here's the full function source.

The Function Signature

function(package, help, pos = 2, lib.loc = NULL,
         character.only = FALSE, logical.return = FALSE,
         warn.conflicts = TRUE, quietly = FALSE,
         verbose = getOption("verbose"))

Arguments Explained

  • package — the name of the library to attach
  • help — optionally summon a help page for the package
  • pos — the position on the search list, given by search()
  • lib.loc — the location of the R library tree to search through, or NULL
  • character.only — whether the package argument is a character vector
  • logical.return — if TRUE, returns TRUE/FALSE indicating success or failure
  • warn.conflicts — warns when there are name conflicts (default TRUE)
  • verbose — triggers additional diagnostic messages
  • quietly — if TRUE, suppress all printing and warnings

Internal Functions

The library() function relies on four internal functions: testRversion, checkLicense, checkNoGenerics, and checkConflicts. They're specified up front in the function body.

How Loading Works

After the internal functions are specified, library() begins with a check of the verbose and quietly arguments:

if (verbose && quietly)
  message("'verbose' and 'quietly' are both true; being verbose then ..")

Next, if lib.loc is NULL (default), it's obtained by .libPaths():

if (!missing(package)) {
  if (is.null(lib.loc))
    lib.loc <- .libPaths()

.libPaths()
## [1] "/Users/statwonk/Library/R/3.2/library"
## [2] "/Library/Frameworks/R.framework/.../library"

Then a quick check that the paths exist — .libPaths() might return a non-existent path:

lib.loc <- lib.loc[dir.exists(lib.loc)]

Quoted vs Unquoted Package Names

library() can be used as library("survival") or without quotes as library(survival). When character.only is FALSE (the default), the substitute function captures the expression and converts it to a character vector.

Key Takeaway: Every library() call walks through path resolution, version checking, license validation, namespace loading, and conflict detection — a deceptively rich function behind R's most common one-liner.

Related R Articles

Discuss an R Development Project