1 Background

R’s vast package ecosystem provides abundant functionality, but packages can also be a source of frustration. Sometimes packages don’t load as expected, and sometimes their dependencies on one another can cause code to break. In this module, we explore some technical details on packages, including how to:

  • check what packages are attached during the current R session and those that are loaded (technically different)

  • check what packages have been installed (i.e., downloaded), even if they’re not attached or loaded in the current session

  • find where installed packages are in your computer

  • remove (detach) packages from the current session

  • unload a package that was loaded via a namespace

  • remove packages from your computer altogether

  • check what packages a package depends on

1.1 Vocabulary: attached to search path vs loaded via a namespace

An “attached” package is one that has been loaded via library() and whose functions are accessible without having to use the :: operator as in package_name::package_function(). For example, if dplyr is attached, I can simply write mutate(); I don’t have to write dplyr::mutate(). Packages that are attached are accessible via what R calls the search path or search list. When a function is used without the double-colon syntax [e.g., mutate()], R looks for a function with that name in the first package on the path, and if it doesn’t find it, it looks in the second package on the path, and so on. The order of the search path can be obtained via searchpaths(). Packages loaded with library() more recently will rank earlier in the search path, which can have consequences for function conflicts.

Packages can also be “loaded via a namespace.” This means that the packages have been loaded because the user called the function using the double-colon operator (package_name::package_function() but has not attached the package to the search path via library(); because R Studio sees that the package is used somewhere in the script, even if the user has not run that code yet; or because the package is needed by the IDE to perform a behind-the-scenes operation. For example, knitr is loaded via a namespace in my current session because I am using R Markdown even though that package does not appear in a script in my current session.

In common usage, I cannot glean any difference between use of a package that has been loaded via namespace versus one that has been installed (e.g., using install.packages("package_name") but has not been loaded at all. To use a function from a package that has already been loaded via a namespace, you still must use the double-colon notation of package_name::package_function(), as you would a function from a package that has not (yet) been loaded via a namespace.

That a package has been loaded via a namespace may, however, have implications for troubleshooting. For example, if you try to install a package that has already been loaded via a namespace, this dialogue box may appear:

To summarize this section, all attached packages are loaded, but not all loaded packages are attached. We will deduce this relationship using functions from the sessioninfo package below. If a package is attached, we can write the function name by itself without its corresponding package name (mindful of potential conflicts); if not, we must use the double-colon notation, ::, and write the package as well.

1.2 Vocabulary: package dependencies

Information related to package dependencies appears, for a given package, in the following fields: Depends, Imports, and Suggests. Package dependencies are covered in this work-in-progress chapter of the book R Packages.

In brief, sometimes you will notice that the installation of a package causes other packages to be installed. This is because that package Imports that package. For any package, this information can be obtained via the available.packages() function, described further below. Suggests is softer. If a package suggests another package, it won’t install that package automatically, but that some features of the package may benefit from functions in that package.

1.3 Resources and references

2 Functions to print information about packages, currently loaded and otherwise

2.1 base R

The following base-R functions provide information about currently loaded or installed packages.

  • utils::sessionInfo(): view R version, attached packages, and packages loaded via a namespace. Also includes package version.

  • base::search(): shows attached packages. Note this also shows other objects on the search path, including the Global Environment.

  • base::loadedNamespaces(): display a list of packages loaded via a namespace.

  • utils::installed.packages() returns all installed packages, whether they’ve been loaded or not.

  • .libPaths() returns the folder location in your computer where packages are stored.

  • All available packages in R (whether installed or not) can be obtained via available.packages(), which returns a matrix of information about every package available in R, including the fields Depends, Imports, LinkingTo, and Suggests These terms are described in the Dependencies chapter of the book R Packages by Hadley Wickham and Jenny Bryan. If a package imports a package, that means it will automatically install that package if the package has not been otherwise installed. This information can then be saved as a dataframe or tibble and explored, demoed below.

These two base-R functions remove (detach) attached packages and unload packages that have been loaded via a namespace. I use the sf package as an example. Note the single colon in "package:sf" is intentional.

2.2 sessioninfo

sessioninfo is a package with functionality similar to that of utils::sessionInfo() but has a nicer output and includes more information about packages.

  • sessioninfo::session_info() prints session information, including a list of packages, their version, and the date the package was built, and the package source (e.g., CRAN or GitHub).

  • sessioninfo::package_info(). By default, this function returns a list of packages that have been loaded in the current session, either by attaching them or via a namespace. In contrast with utils::sessionInfo(), this function by default does not show base-R functions. Note that at the bottom of the output, the location where packages are stored is shown. You can further specify what types of packages are returned by sessioninfo::package_info():

  • sessioninfo::package_info(pkgs = "loaded") returns all loaded packages (default called explicitly).

  • sessioninfo::package_info(pkgs = "attached") returns only those packages have been attached to the search path, i.e., via library().

  • sessioninfo::package_info(pkgs = "installed") returns all installed packages, whether they’ve been loaded or not.

3 Functions to install, update, and remove packages (base R)

We already know that packages are installed via install.packages("package_name"). We can use the dependencies argument to further specify whether or not to also install dependencies. The default behavior is NA, elaborated upon here.

  • install.packages("package_name", dependencies = FALSE) will install the package without its dependencies. This may be useful if you already know that all dependencies for a given package have been installed.

To update packages that are already loaded, use

update.packages(checkBuilt = T, ask = F).

To remove packages from either the search path or a namespace, use:

  • base::detach("package:sf", unload = TRUE). Note if unload=FALSE, the package may remain in a namespace.

  • base::unloadNamespace("package_name") unloads a namespace.

To remove packages that have been instaslled:

4 Demo of functions

I’m going to load attach two packages, here and ggplot2, and demo some of the above functions. Note that the base R sessionInfo() tells us that just one package, here, was attached. Some other packages have been loaded via a namespace.

library(here)
## here() starts at /Users/michaeldgarber/Dropbox/Work/teach/teach-r
library(ggplot2)
sessionInfo()
## R version 4.2.0 (2022-04-22)
## Platform: aarch64-apple-darwin20 (64-bit)
## Running under: macOS Monterey 12.5.1
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/lib/libRlapack.dylib
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] ggplot2_3.3.6 here_1.0.1   
## 
## loaded via a namespace (and not attached):
##  [1] bslib_0.4.0      compiler_4.2.0   pillar_1.8.0     jquerylib_0.1.4 
##  [5] tools_4.2.0      digest_0.6.29    jsonlite_1.8.0   evaluate_0.15   
##  [9] lifecycle_1.0.1  tibble_3.1.8     gtable_0.3.0     pkgconfig_2.0.3 
## [13] rlang_1.0.4      DBI_1.1.3        cli_3.3.0        rstudioapi_0.13 
## [17] yaml_2.3.5       xfun_0.31        fastmap_1.1.0    withr_2.5.0     
## [21] dplyr_1.0.9      stringr_1.4.0    knitr_1.39       generics_0.1.3  
## [25] sass_0.4.2       vctrs_0.4.1      tidyselect_1.1.2 rprojroot_2.0.3 
## [29] grid_4.2.0       glue_1.6.2       R6_2.5.1         fansi_1.0.3     
## [33] rmarkdown_2.14   bookdown_0.27    purrr_0.3.4      magrittr_2.0.3  
## [37] scales_1.2.0     htmltools_0.5.3  assertthat_0.2.1 colorspace_2.0-3
## [41] utf8_1.2.2       stringi_1.7.8    munsell_0.5.0    cachem_1.0.6

4.1 General session info

sessioninfo::session_info()

Now let’s get the same information using sessioninfo::session_info(). Note the asterisk next to the packages we attached.

sessioninfo::session_info()
## ─ Session info ───────────────────────────────────────────────────────────────
##  setting  value
##  version  R version 4.2.0 (2022-04-22)
##  os       macOS Monterey 12.5.1
##  system   aarch64, darwin20
##  ui       X11
##  language (EN)
##  collate  en_US.UTF-8
##  ctype    en_US.UTF-8
##  tz       America/Denver
##  date     2022-08-23
##  pandoc   2.18 @ /Applications/RStudio.app/Contents/MacOS/quarto/bin/tools/ (via rmarkdown)
## 
## ─ Packages ───────────────────────────────────────────────────────────────────
##  package     * version date (UTC) lib source
##  assertthat    0.2.1   2019-03-21 [1] CRAN (R 4.2.0)
##  bookdown      0.27    2022-06-14 [1] CRAN (R 4.2.0)
##  bslib         0.4.0   2022-07-16 [1] CRAN (R 4.2.0)
##  cachem        1.0.6   2021-08-19 [1] CRAN (R 4.2.0)
##  cli           3.3.0   2022-04-25 [1] CRAN (R 4.2.0)
##  colorspace    2.0-3   2022-02-21 [1] CRAN (R 4.2.0)
##  DBI           1.1.3   2022-06-18 [1] CRAN (R 4.2.0)
##  digest        0.6.29  2021-12-01 [1] CRAN (R 4.2.0)
##  dplyr         1.0.9   2022-04-28 [1] CRAN (R 4.2.0)
##  evaluate      0.15    2022-02-18 [1] CRAN (R 4.2.0)
##  fansi         1.0.3   2022-03-24 [1] CRAN (R 4.2.0)
##  fastmap       1.1.0   2021-01-25 [1] CRAN (R 4.2.0)
##  generics      0.1.3   2022-07-05 [1] CRAN (R 4.2.0)
##  ggplot2     * 3.3.6   2022-05-03 [1] CRAN (R 4.2.0)
##  glue          1.6.2   2022-02-24 [1] CRAN (R 4.2.0)
##  gtable        0.3.0   2019-03-25 [1] CRAN (R 4.2.0)
##  here        * 1.0.1   2020-12-13 [1] CRAN (R 4.2.0)
##  htmltools     0.5.3   2022-07-18 [1] CRAN (R 4.2.0)
##  jquerylib     0.1.4   2021-04-26 [1] CRAN (R 4.2.0)
##  jsonlite      1.8.0   2022-02-22 [1] CRAN (R 4.2.0)
##  knitr         1.39    2022-04-26 [1] CRAN (R 4.2.0)
##  lifecycle     1.0.1   2021-09-24 [1] CRAN (R 4.2.0)
##  magrittr      2.0.3   2022-03-30 [1] CRAN (R 4.2.0)
##  munsell       0.5.0   2018-06-12 [1] CRAN (R 4.2.0)
##  pillar        1.8.0   2022-07-18 [1] CRAN (R 4.2.0)
##  pkgconfig     2.0.3   2019-09-22 [1] CRAN (R 4.2.0)
##  purrr         0.3.4   2020-04-17 [1] CRAN (R 4.2.0)
##  R6            2.5.1   2021-08-19 [1] CRAN (R 4.2.0)
##  rlang         1.0.4   2022-07-12 [1] CRAN (R 4.2.0)
##  rmarkdown     2.14    2022-04-25 [1] CRAN (R 4.2.0)
##  rprojroot     2.0.3   2022-04-02 [1] CRAN (R 4.2.0)
##  rstudioapi    0.13    2020-11-12 [1] CRAN (R 4.2.0)
##  sass          0.4.2   2022-07-16 [1] CRAN (R 4.2.0)
##  scales        1.2.0   2022-04-13 [1] CRAN (R 4.2.0)
##  sessioninfo   1.2.2   2021-12-06 [1] CRAN (R 4.2.0)
##  stringi       1.7.8   2022-07-11 [1] CRAN (R 4.2.0)
##  stringr       1.4.0   2019-02-10 [1] CRAN (R 4.2.0)
##  tibble        3.1.8   2022-07-22 [1] CRAN (R 4.2.0)
##  tidyselect    1.1.2   2022-02-21 [1] CRAN (R 4.2.0)
##  utf8          1.2.2   2021-07-24 [1] CRAN (R 4.2.0)
##  vctrs         0.4.1   2022-04-13 [1] CRAN (R 4.2.0)
##  withr         2.5.0   2022-03-03 [1] CRAN (R 4.2.0)
##  xfun          0.31    2022-05-10 [1] CRAN (R 4.2.0)
##  yaml          2.3.5   2022-02-21 [1] CRAN (R 4.2.0)
## 
##  [1] /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/library
## 
## ──────────────────────────────────────────────────────────────────────────────

4.2 Explore package info and detach packages

Now let’s specify what type of packages we want to see from sessioninfo::package_info()

Look at all packages that have been loaded.

sessioninfo::package_info("loaded")
##  package     * version date (UTC) lib source
##  assertthat    0.2.1   2019-03-21 [1] CRAN (R 4.2.0)
##  bookdown      0.27    2022-06-14 [1] CRAN (R 4.2.0)
##  bslib         0.4.0   2022-07-16 [1] CRAN (R 4.2.0)
##  cachem        1.0.6   2021-08-19 [1] CRAN (R 4.2.0)
##  cli           3.3.0   2022-04-25 [1] CRAN (R 4.2.0)
##  colorspace    2.0-3   2022-02-21 [1] CRAN (R 4.2.0)
##  DBI           1.1.3   2022-06-18 [1] CRAN (R 4.2.0)
##  digest        0.6.29  2021-12-01 [1] CRAN (R 4.2.0)
##  dplyr         1.0.9   2022-04-28 [1] CRAN (R 4.2.0)
##  evaluate      0.15    2022-02-18 [1] CRAN (R 4.2.0)
##  fansi         1.0.3   2022-03-24 [1] CRAN (R 4.2.0)
##  fastmap       1.1.0   2021-01-25 [1] CRAN (R 4.2.0)
##  generics      0.1.3   2022-07-05 [1] CRAN (R 4.2.0)
##  ggplot2     * 3.3.6   2022-05-03 [1] CRAN (R 4.2.0)
##  glue          1.6.2   2022-02-24 [1] CRAN (R 4.2.0)
##  gtable        0.3.0   2019-03-25 [1] CRAN (R 4.2.0)
##  here        * 1.0.1   2020-12-13 [1] CRAN (R 4.2.0)
##  htmltools     0.5.3   2022-07-18 [1] CRAN (R 4.2.0)
##  jquerylib     0.1.4   2021-04-26 [1] CRAN (R 4.2.0)
##  jsonlite      1.8.0   2022-02-22 [1] CRAN (R 4.2.0)
##  knitr         1.39    2022-04-26 [1] CRAN (R 4.2.0)
##  lifecycle     1.0.1   2021-09-24 [1] CRAN (R 4.2.0)
##  magrittr      2.0.3   2022-03-30 [1] CRAN (R 4.2.0)
##  munsell       0.5.0   2018-06-12 [1] CRAN (R 4.2.0)
##  pillar        1.8.0   2022-07-18 [1] CRAN (R 4.2.0)
##  pkgconfig     2.0.3   2019-09-22 [1] CRAN (R 4.2.0)
##  purrr         0.3.4   2020-04-17 [1] CRAN (R 4.2.0)
##  R6            2.5.1   2021-08-19 [1] CRAN (R 4.2.0)
##  rlang         1.0.4   2022-07-12 [1] CRAN (R 4.2.0)
##  rmarkdown     2.14    2022-04-25 [1] CRAN (R 4.2.0)
##  rprojroot     2.0.3   2022-04-02 [1] CRAN (R 4.2.0)
##  rstudioapi    0.13    2020-11-12 [1] CRAN (R 4.2.0)
##  sass          0.4.2   2022-07-16 [1] CRAN (R 4.2.0)
##  scales        1.2.0   2022-04-13 [1] CRAN (R 4.2.0)
##  sessioninfo   1.2.2   2021-12-06 [1] CRAN (R 4.2.0)
##  stringi       1.7.8   2022-07-11 [1] CRAN (R 4.2.0)
##  stringr       1.4.0   2019-02-10 [1] CRAN (R 4.2.0)
##  tibble        3.1.8   2022-07-22 [1] CRAN (R 4.2.0)
##  tidyselect    1.1.2   2022-02-21 [1] CRAN (R 4.2.0)
##  utf8          1.2.2   2021-07-24 [1] CRAN (R 4.2.0)
##  vctrs         0.4.1   2022-04-13 [1] CRAN (R 4.2.0)
##  withr         2.5.0   2022-03-03 [1] CRAN (R 4.2.0)
##  xfun          0.31    2022-05-10 [1] CRAN (R 4.2.0)
##  yaml          2.3.5   2022-02-21 [1] CRAN (R 4.2.0)
## 
##  [1] /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/library

Look at only those package(s) that have been attached:

sessioninfo::package_info("attached")
##  package * version date (UTC) lib source
##  ggplot2 * 3.3.6   2022-05-03 [1] CRAN (R 4.2.0)
##  here    * 1.0.1   2020-12-13 [1] CRAN (R 4.2.0)
## 
##  [1] /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/library

Note that the result of sessioninfo::package_info("attached") is a subset of sessioninfo::package_info("loaded"), implying that all attached packages are loaded.

I’m not going to print all installed packages, because the list is long, but that would be done by

sessioninfo::package_info("installed")

If we remove here using detach(), is it removed from the list of attached packages?

base::detach("package:here", unload = TRUE)
sessioninfo::package_info("attached")
##  package * version date (UTC) lib source
##  ggplot2 * 3.3.6   2022-05-03 [1] CRAN (R 4.2.0)
## 
##  [1] /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/library

4.3 Remove a package

Above, we detached the here package from the current session, but it’s still available as an installed package. We can check this via sessioninfo::package_info("installed"). Rather than print the entire list of installed packages in this demo (long), I’m going to create an object corresponding to the installed packages and then filter only to the here package using dplyr functions.

library(tidyverse) #so that the pipe will work
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
## ✔ tibble  3.1.8     ✔ dplyr   1.0.9
## ✔ tidyr   1.2.0     ✔ stringr 1.4.0
## ✔ readr   2.1.2     ✔ forcats 0.5.1
## ✔ purrr   0.3.4     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
installed_packages_here = sessioninfo::package_info("installed") %>% 
  dplyr::as_tibble() %>% 
  dplyr::filter(package == "here")

installed_packages_here
## # A tibble: 1 × 11
##   package ondiskversion loade…¹ path  loade…² attac…³ is_base date  source md5ok
##   <chr>   <chr>         <chr>   <chr> <chr>   <lgl>   <lgl>   <chr> <chr>  <lgl>
## 1 here    1.0.1         <NA>    /Lib… <NA>    FALSE   FALSE   2020… CRAN … NA   
## # … with 1 more variable: library <fct>, and abbreviated variable names
## #   ¹​loadedversion, ²​loadedpath, ³​attached
## # ℹ Use `colnames()` to see all variable names

Remove the here package. Note we now get an error when we try to run here::here() because the package is nowhere to be found.

remove.packages("here")
## Removing package from '/Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/library'
## (as 'lib' is unspecified)
here::here()
## Error in loadNamespace(x): there is no package called 'here'

Re-install it.

install.packages("here")
## 
## The downloaded binary packages are in
##  /var/folders/sd/fx5w2bb91wxbnndc3hpqvtcr0000gn/T//Rtmp8nrJAd/downloaded_packages

4.4 Examine package dependencies

We can save the information about all available R packages to an object called packages and then convert that object (a matrix) into an easier-to-manage tibble, and then use dplyr functions to filter to one specific package.

We see, for example, that tidycensus Imports sf, among other packages.

packages  = utils::available.packages()

library(tidyverse) #so the pipe works
packages_tibble_tidycensus = packages %>% 
  dplyr::as_tibble() %>% 
  dplyr::filter(Package == "tidycensus")

#Just select these two fields.
packages_tibble_tidycensus %>% 
  dplyr::select(Package, Imports)
## # A tibble: 1 × 2
##   Package    Imports                                                            
##   <chr>      <chr>                                                              
## 1 tidycensus "httr, sf, dplyr (>= 1.0.0), tigris, stringr, jsonlite (>=\n1.5.0)…

5 Use the graphical user interface to manage packages

In R Studio, many (not all, to my knowledge) of the above functions to load packages, examine which packages are loaded or installed, and update packages can be done via the point-and-click interface.

For example, to install packages, we can use the Tools dropdown,

which leads to

Checking for package updates can also be done from the Tools dropdown,

or from the Packages tab (usually bottom right) of R Studio by clicking the “Update” icon.

This pane shows a list of all packages that have been installed, and those that have been attached have a check mark.

Packages on the search path (attached) can also be seen from this dropdown. The only package of the below that I loaded explicitly was here.

This shows the same information as searchpaths().



Copyright © 2022 Michael D. Garber