Chapter 6 Bonus Chapter: Accessing R Source Code, Package Internals, and Repositories

One of R’s greatest strengths is that it is completely open source. This means you do not have to treat R functions, packages, or interactive widgets as “black boxes.” Every line of R code written by other developers—including R’s core team—is available for you to inspect, study, and modify.

This bonus chapter explains how to access, extract, and inspect R source code from within R itself, from CRAN/GitHub repositories, and from web portals like rdrr.io.


6.1 Accessing Source Code Directly within R

1. Inspecting Standard R Functions

The easiest way to view the source code of any R function is to type the function’s name in the Console without parentheses and press Enter:

# Define the function in this session
skewness_manual <- function(x) {
  n <- length(x)
  m <- mean(x)
  (sum((x - m)^3) / n) / (sum((x - m)^2) / n)^(3/2)
}

# View the source code by printing its name without parentheses
skewness_manual
## function (x) 
## {
##     n <- length(x)
##     m <- mean(x)
##     (sum((x - m)^3)/n)/(sum((x - m)^2)/n)^(3/2)
## }

For package functions, simply load the package first or use the namespace operator :::

library(psych)
# View the source code of the skew function from the psych package
psych::skew
## function (x, na.rm = TRUE, type = 3) 
## {
##     if (length(dim(x)) == 0) {
##         if (na.rm) {
##             x <- x[!is.na(x)]
##         }
##         sdx <- sd(x, na.rm = na.rm)
##         mx <- mean(x)
##         n <- length(x[!is.na(x)])
##         switch(type, {
##             skewer <- sqrt(n) * (sum((x - mx)^3, na.rm = na.rm)/(sum((x - 
##                 mx)^2, na.rm = na.rm)^(3/2)))
##         }, {
##             skewer <- n * sqrt(n - 1) * (sum((x - mx)^3, na.rm = na.rm)/((n - 
##                 2) * sum((x - mx)^2, na.rm = na.rm)^(3/2)))
##         }, {
##             skewer <- sum((x - mx)^3)/(n * sd(x)^3)
##         })
##     }
##     else {
##         skewer <- rep(NA, dim(x)[2])
##         if (is.matrix(x)) {
##             mx <- colMeans(x, na.rm = na.rm)
##         }
##         else {
##             mx <- apply(x, 2, mean, na.rm = na.rm)
##         }
##         sdx <- apply(x, 2, sd, na.rm = na.rm)
##         for (i in 1:dim(x)[2]) {
##             n <- length(x[!is.na(x[, i]), i])
##             switch(type, {
##                 skewer[i] <- sqrt(n) * (sum((x[, i] - mx[i])^3, 
##                   na.rm = na.rm)/(sum((x[, i] - mx[i])^2, na.rm = na.rm)^(3/2)))
##             }, {
##                 skewer[i] <- n * sqrt(n - 1) * (sum((x[, i] - 
##                   mx[i])^3, na.rm = na.rm)/((n - 2) * sum((x[, 
##                   i] - mx[i])^2, na.rm = na.rm)^(3/2)))
##             }, {
##                 skewer[i] <- sum((x[, i] - mx[i])^3, na.rm = na.rm)/(n * 
##                   sdx[i]^3)
##             })
##         }
##     }
##     return(skewer)
## }
## <bytecode: 0x5562d575ceb0>
## <environment: namespace:psych>

2. Accessing Unexported (Hidden) Functions

Many packages contain private helper functions that are not exported to the user workspace. If you try to view them using package::function_name, R will throw an error. To view these unexported functions, use the triple colon (:::) operator or the getAnywhere() function:

# Attempting this will fail as it is unexported
psych::skew.default 

# This works! Accessing the unexported S3 method directly
psych:::skew.default

# Alternatively, search all loaded namespaces for the function
getAnywhere("skew.default")

3. Primitive and Internal C/Fortran Code

Some core R functions operate at a very low level for performance. When you print their source code, you will see .Primitive() or .Internal():

# Print the sum function
sum
## function (..., na.rm = FALSE)  .Primitive("sum")

These functions call compiled C or Fortran code directly. To inspect this code, you must view the official R source code repository (e.g., in the src/main/ directory of the R source code).


6.2 Inspecting Code Online via rdrr.io

If you do not have R open or want a convenient, searchable web-based interface to read R code, the rdrr.io portal is an invaluable tool.

  • What it is: rdrr.io is an online package index that hosts the documentation, source code, and dependency maps for all CRAN, Bioconductor, and popular GitHub R packages.
  • How to use it:
    1. Go to https://rdrr.io/ in your browser.
    2. Search for any package (e.g., psych) or specific function (e.g., cohen.kappa).
    3. Under the package page, click on “Source code” to browse the package’s internal file structure.
    4. Navigate to the R/ directory. All R functions are defined here. For example, you can read the raw R source for the skew() function at rdrr.io/cran/psych/src/R/skew.R.

6.3 Accessing Code from Repositories (CRAN & GitHub)

1. Downloading Package Source Tarballs from CRAN

CRAN stores every R package in two formats: compiled binary files (for users to install) and raw source archives (called tarballs, ending in .tar.gz). To inspect a package’s full structure, including non-R assets like C++ code or raw datasets:

  1. Go to the package’s CRAN page (e.g., https://cran.r-project.org/package=psych).

  2. Download the Package source file (e.g., psych_2.4.4.tar.gz).

  3. Extract the archive using an archiving utility (like 7-Zip on Windows) or from R itself:

    # Download and unpack a package source archive manually
    download.file("https://cran.r-project.org/src/contrib/psych_2.4.4.tar.gz", "psych.tar.gz")
    untar("psych.tar.gz", exdir = "psych_source")
  4. Open the extracted directory. You will see a standard R package structure:

    • R/: Contains all R code files.
    • src/: Contains compiled C, C++, or Fortran code files (if the package uses them).
    • man/: Contains the documentation files (written in .Rd format).
    • inst/: Contains extra installed assets, templates, and raw resource files.

2. Exploring Code on GitHub

Most modern R packages are developed openly on GitHub before being published on CRAN. GitHub provides code versioning history, allowing you to see exactly how a function’s code has changed over time.

  • To find a package’s development code, search GitHub or look for the “URL” field on the package’s CRAN page.

  • You can install the bleeding-edge developer version of any GitHub-hosted R package using the remotes package:

    # Install directly from a GitHub repository
    remotes::install_github("personality-project/psych")

6.4 Accessing HTML Widgets and Assets

R Markdown and Shiny support interactive components called HTML Widgets (powered by the htmlwidgets package). These widgets (such as interactive maps in leaflet or datatables in DT) bridge R and JavaScript.

To inspect how an HTML widget works: 1. Locate where R stores installed packages on your local system using find.package():

# Locate the installation path of the DT package
find.package("DT")
  1. Navigate to the htmlwidgets/ subfolder inside that path: system.file("htmlwidgets", package = "DT")
  2. Inside this directory, you will find:
    • The R binding script (e.g., datatable.R which defines the R parameters).
    • The JavaScript binding script (e.g., datatables.js which initializes the JS library).
    • The .yaml configuration file mapping R arguments to JavaScript assets.