How to Tell What Packages You Have Used in R

How can I see what are packages being used for in an R script, and which packages are currently not used?

I have been looking for a clear answer to this and finally, building on the useful function pointed out by @eh21 here, I built up this small approach that fits the intention with 3 lines of code and that can be replicated by anyone (and with this I mean by non-experienced programmes like me) on their case with no effort.

The principle is to use this approach after the packages have been loaded and before the actual project code (i.e. no need for it to be run in order to get the desired information), as below:

# Load packages ----

packageload <- c("ggplot2", "readxl")
lapply(packageload, library, character.only = TRUE)

# Find which packages do used functions belong to ----

used.functions <- NCmisc::list.functions.in.file(filename = "thisfile.R", alphabetic = FALSE) |> print()

# Find which loaded packages are not used ----

used.packages <- used.functions |> names() |> grep(pattern = "packages:", value = TRUE) |> gsub(pattern = "package:", replacement = "") |> print()

unused.packages <- packageload[!(packageload %in% used.packages)] |> print()

# Actual project code (no need to be run) ----

ggplot(diamonds, aes(x = cut)) +
geom_bar()

The relevant outputs are:

> used.packages
[1] "base" "ggplot2"

> used.functions
$`character(0)`
[1] "list.functions.in.file"

$`package:base`
[1] "c" "lapply" "print" "names" "grep" "gsub"

$`package:ggplot2`
[1] "ggplot" "aes" "geom_bar"

> unused.packages
[1] "readxl"

Notes:

  • This requires install.packages("NCmisc"), however I didn't load that package (and used :: instead) for consistency, as it shouldn't appear among the used.packages;
  • if using RStudio and wanting to apply this to multiple scripts, using rstudioapi::getSourceEditorContext()$path instead of "thisfile.R" in NCmisc::list.functions.in.file will be handy.
  • The approach above works for the case in which lapply() is used on a named object to load packages. If packages are instead loaded without resorting to a named object (e.g. with a series of library() or require()), the # Load packages ---- section of the code above can be modified as follows:
# Load packages ----

packageload <- search()

library(ggplot2)
library(readxl)

packageload <- search()[!(search() %in% packageload)] |> grep(pattern = "package:", value = TRUE) |> gsub(pattern = "package:", replacement = "")

How to find out which package version is loaded in R?

You can use sessionInfo() to accomplish that.

> sessionInfo()
R version 2.15.0 (2012-03-30)
Platform: x86_64-pc-linux-gnu (64-bit)

locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 LC_PAPER=C LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] graphics grDevices utils datasets stats grid methods base

other attached packages:
[1] ggplot2_0.9.0 reshape2_1.2.1 plyr_1.7.1

loaded via a namespace (and not attached):
[1] colorspace_1.1-1 dichromat_1.2-4 digest_0.5.2 MASS_7.3-18 memoise_0.1 munsell_0.3
[7] proto_0.3-9.2 RColorBrewer_1.0-5 scales_0.2.0 stringr_0.6
>

However, as per comments and the answer below, there are better options

> packageVersion("snow")

[1] ‘0.3.9’

Or:

"Rmpi" %in% loadedNamespaces()

How can I tell which packages I am not using in my R script?

Update 2020-04-13

I've now updated the referenced function to use the abstract syntax tree (AST) instead of using regular expressions as before. This is a much more robust way of approaching the problem (it's still not completely ironclad). This is available from version 0.2.0 of funchir, now on CRAN.


I've just got around to writing a quick-and-dirty function to handle this which I call stale_package_check, and I've added it to my package (funchir).

e.g., if we save the following script as test.R:

library(data.table)
library(iotools)
DT = data.table(a = 1:3)

Then (from the directory with that script) run funchir::stale_package_check('test.R'), we'll get:

Functions matched from package data.table: data.table

**No exported functions matched from iotools**

determine which packages are used

An answer based on ideas in the question comments. The key functions are getParseData() and packageName().

# create an R file that uses a few functions

fileConn<-file("test.R")
writeLines(c("df <- data.frame(v1=c(1, 1, 1), v2=c(1, 2, 3))",
"\n",
"m <- mean(df$v2)",
"\n",
"describe(df) #psych package"),
fileConn)
close(fileConn)

# getParseData approach
pkg <- getParseData(parse("test.R"))
pkg <- pkg[pkg$token=="SYMBOL_FUNCTION_CALL",]
pkg <- pkg[!duplicated(pkg$text),]
pkgname <- pkg$text
pkgname
# [1] "data.frame" "c" "mean" "describe"

# load all probable packages first
pkgList <- list(pkgname)
for (i in 1:length(pkgname)) {
try(print(packageName(environment(get(pkgList[[1]][i])))))
}

#[1] "base"
#Error in packageName(environment(get(pkgList[[1]][i]))) :
# 'env' must be an environment
#[1] "base"
#[1] "psych"

I'll mark this as correct for now, but happy to consider other solutions.

Is there a file on R projects where I can find out which packages and which versions are installed?

I achieved that using renv

  1. renv::init()
  2. renv::settings$snapshot.type("all") # if you want to list all
  3. renv::snapshot()

Then the renv.lock file will be updated with the state of the project libraries where you can find all libraries listed. Something similar to this:

{
"R": {
"Version": "4.0.3",
"Repositories": [
{
"Name": "CRAN",
"URL": "https://cran.rstudio.com"
}
]
},
"Packages": {
"KernSmooth": {
"Package": "KernSmooth",
"Version": "2.23-17",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "bbff70c8c0357b5b88238c83f680fcd3"
},
"MASS": {
"Package": "MASS",
"Version": "7.3-53",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "d1bc1c8e9c0ace57ec9ffea01021d45f"
},
"Matrix": {
"Package": "Matrix",
"Version": "1.2-18",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "08588806cba69f04797dab50627428ed"
},
"R6": {
"Package": "R6",
"Version": "2.5.0",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "b203113193e70978a696b2809525649d"
},
"Rcpp": {
"Package": "Rcpp",
"Version": "1.0.5",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "125dc7a0ed375eb68c0ce533b48d291f"
},
"assertthat": {
"Package": "assertthat",
"Version": "0.2.1",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "50c838a310445e954bc13f26f26a6ecf"
},
"boot": {
"Package": "boot",
"Version": "1.3-25",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "bd51734a754b6c2baf28b2d1ebc11e91"
},
"class": {
"Package": "class",
"Version": "7.3-17",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "9267f5dab59a4ef44229858a142bded1"
},
"cli": {
"Package": "cli",
"Version": "2.2.0",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "3ef298932294b775fa0a3eeaa3a645b0"
},
"cluster": {
"Package": "cluster",
"Version": "2.1.0",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "db63a44aab5aadcb6bf2f129751d129a"
},
"codetools": {
"Package": "codetools",
"Version": "0.2-16",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "89cf4b8207269ccf82fbeb6473fd662b"
},
"crayon": {
"Package": "crayon",
"Version": "1.3.4",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "0d57bc8e27b7ba9e45dba825ebc0de6b"
},
"digest": {
"Package": "digest",
"Version": "0.6.27",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "a0cbe758a531d054b537d16dff4d58a1"
},
"dplyr": {
"Package": "dplyr",
"Version": "1.0.2",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "d0509913b27ea898189ee664b6030dc2"
},
"ellipsis": {
"Package": "ellipsis",
"Version": "0.3.1",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "fd2844b3a43ae2d27e70ece2df1b4e2a"
},
"fansi": {
"Package": "fansi",
"Version": "0.4.1",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "7fce217eaaf8016e72065e85c73027b5"
},
"foreign": {
"Package": "foreign",
"Version": "0.8-80",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "ae1b1e15cc6ccb2bc61c0ac33e86d35f"
},
"generics": {
"Package": "generics",
"Version": "0.1.0",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "4d243a9c10b00589889fe32314ffd902"
},
"glue": {
"Package": "glue",
"Version": "1.4.2",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "6efd734b14c6471cfe443345f3e35e29"
},
"lattice": {
"Package": "lattice",
"Version": "0.20-41",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "fbd9285028b0263d76d18c95ae51a53d"
},
"lifecycle": {
"Package": "lifecycle",
"Version": "0.2.0",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "361811f31f71f8a617a9a68bf63f1f42"
},
"magrittr": {
"Package": "magrittr",
"Version": "2.0.1",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "41287f1ac7d28a92f0a286ed507928d3"
},
"mgcv": {
"Package": "mgcv",
"Version": "1.8-33",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "eb7b6439bc6d812eed2cddba5edc6be3"
},
"nlme": {
"Package": "nlme",
"Version": "3.1-149",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "7c24ab3a1e3afe50388eb2d893aab255"
},
"nnet": {
"Package": "nnet",
"Version": "7.3-14",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "0d87e50e11394a7151a28873637d799a"
},
"pillar": {
"Package": "pillar",
"Version": "1.4.7",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "3b3dd89b2ee115a8b54e93a34cd546b4"
},
"pkgconfig": {
"Package": "pkgconfig",
"Version": "2.0.3",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "01f28d4278f15c76cddbea05899c5d6f"
},
"plyr": {
"Package": "plyr",
"Version": "1.8.6",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "ec0e5ab4e5f851f6ef32cd1d1984957f"
},
"purrr": {
"Package": "purrr",
"Version": "0.3.4",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "97def703420c8ab10d8f0e6c72101e02"
},
"remotes": {
"Package": "remotes",
"Version": "2.2.0",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "430a0908aee75b1fcba0e62857cab0ce"
},
"renv": {
"Package": "renv",
"Version": "0.12.3-8",
"Source": "GitHub",
"RemoteType": "github",
"RemoteHost": "api.github.com",
"RemoteRepo": "renv",
"RemoteUsername": "rstudio",
"RemoteRef": "HEAD",
"RemoteSha": "080234134766804fb1dbbd777dff77dffff4b2e6",
"Hash": "cf80821fca4292cf8af159b24d422536"
},
"rlang": {
"Package": "rlang",
"Version": "0.4.9",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "9d7aba7bed9a79e2403b4777428a2b12"
},
"rpart": {
"Package": "rpart",
"Version": "4.1-15",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "9787c1fcb680e655d062e7611cadf78e"
},
"spatial": {
"Package": "spatial",
"Version": "7.3-12",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "58a02ce0150652b96c044bc67a0df2e5"
},
"survival": {
"Package": "survival",
"Version": "3.2-7",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "39c4ac6d22dad33db0ee37b40810ea12"
},
"tibble": {
"Package": "tibble",
"Version": "3.0.4",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "71dffd8544691c520dd8e41ed2d7e070"
},
"tidyselect": {
"Package": "tidyselect",
"Version": "1.1.0",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "6ea435c354e8448819627cf686f66e0a"
},
"utf8": {
"Package": "utf8",
"Version": "1.1.4",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "4a5081acfb7b81a572e4384a7aaf2af1"
},
"vctrs": {
"Package": "vctrs",
"Version": "0.3.5",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "d25c5bea636cf892edbfd64fc3d20c20"
}
}
}

Is there a command in R to view all the functions present in a package?

You can use lsf.str.

For instance:

lsf.str("package:dplyr")

To list all objects in the package use ls

ls("package:dplyr")

Note that the package must be attached.

To see the list of currently loaded packages use

search()

Alternatively calling the help would also do, even if the package is not attached:

help(package = dplyr)

Finally, you can use RStudio which provides an autocomplete function. So, for instance, typing dplyr:: in the console or while editing a file will result in a popup list of all dplyr functions/objects.

How do I determine what packages are dependent on a given package in R?

You can use installed.packages which gives the list of all your installed packages with their dependencies (as a matrix object). Say for instance that you want to find which packages are dependent on rJava:

#get my installed packages
x<-installed.packages()
#find packages dependent on rJava
x[grepl("rJava",x[,"Depends"]),"Package"]
#the result for my R installation
# XLConnect xlsx xlsxjars
#"XLConnect" "xlsx" "xlsxjars"

How to find how a package was loaded in R?

I'm not an R-internals or R-Core guy, so some of this is speculation and understanding on my part.

If a package imports functions from another package, either one-by-one or the whole other-package, then those functions should not be inserted into your search path. For example, dplyr is a fairly complex package that imports from several other packages and optionally re-exports some of them. For instance, from its NAMESPACE:

importFrom(R6,R6Class)

but if you library(dplyr) and then type in R6Class, it reports Error: object 'R6Class' not found. However, it is visible to dplyr functions:

> R6Class
Error: object 'R6Class' not found
> debug(dplyr::mutate)
> mutate(mtcars, cyl = 5)
debugging in: mutate(mtcars, cyl = 5)
debug: {
UseMethod("mutate")
}
Browse[2]> R6Class
function (classname = NULL, public = list(), private = NULL,
active = NULL, inherit = NULL, lock_objects = TRUE, class = TRUE,
portable = TRUE, lock_class = FALSE, cloneable = TRUE, parent_env = parent.frame(),
lock)
{
...

This works now because the search path within dplyr::mutate is from dplyr's perspective, not the user's perspective.

Combine with this my doubt (though not certainty) that those packages would call library(data.table), importing the package into your search path.

More than likely, there is a package imported by one of the packages you just listed (a second-generation dependency-import, I guess) that is improperly referencing wday by itself, and it just starts working when some higher package is properly loaded, bringing that function into its effective search path.

I suggest two ways to find what is going wrong:

  1. When you see an error, run traceback() and look at the stack of function calls; it'll take some sleuthing, but find where that wday is being called, find that function in the packages (both exported and internal functions!), and go from there.

  2. If all packages are being thorough in announcing packages they import (via Depends:, Imports:, or perhaps even a mis-used Suggests:), then you can hunt down where nested dependencies go with something like this.

    pkgs <- trimws(unlist(strsplit(gsub("library\\(([^)]*)\\)", "\\1", "library(qmao);library(chron);library(tseries);library(iterators);library(erer);
    library(corpcor); library(zoo); library(xts); library(quantmod);
    library(TTR); library(graphics); library(ggplot2); library(gsee);
    library(tseries); library(quantstrat); library(plyr); library(caTools);
    library(zoo); library(chron); library(gtools); library(microbenchmark);
    library(benchmark); library(rbenchmark); library(utils); library(Rcpp);
    library(RcppXts); library(RcppArmadillo); library(gtools); library(rcppbugs);
    library(RcppClassic); library(RcppStreams); library(inline); library(RcppEigen);
    library(RcppParallel); library(RcppProgress); library(doParallel); library(parallel);
    library(foreach); library(doMC); library(doSNOW); library(fGarch); library(FitAR);
    library(fUnitRoots); library(dplyr);"), ";")))
    # just so I can search locally on mine without all of those packages
    inst_pkgs <- installed.packages()
    pkgs <- intersect(pkgs, inst_pkgs[,1])

    # inexact but "good enough" for now
    possibles <- Filter(function(a) any(grepl("data.table|lubridate", a)),
    sapply(pkgs, function(p) unlist(packageDescription(p)[c("Depends","Imports","Suggests")])))
    names(possibles)
    # [1] "dplyr"

    You can find more info by looking at the full details of that package:

    possibles[[1]]["Suggests"]
    # Suggests
    # "bit64 (>= 0.9.7), callr (>= 3.1.1), covr (>= 3.0.1), DBI (>=\n0.7.14), dbplyr (>= 1.2.0), dtplyr (>= 0.0.2), ggplot2 (>=\n2.2.1), hms (>= 0.4.1), knitr (>= 1.19), Lahman (>= 3.0-1),\nlubridate (>= 1.7.4), MASS, mgcv (>= 1.8.23), microbenchmark\n(>= 1.4.4), nycflights13 (>= 0.2.2), rmarkdown (>= 1.8), RMySQL\n(>= 0.10.13), RPostgreSQL (>= 0.6.2), RSQLite (>= 2.0),\ntestthat (>= 2.0.0), withr (>= 2.1.1), broom (>= 0.5.1), purrr\n(>= 0.3.0), readr (>= 1.3.1), crayon (>= 1.3.4)"


Related Topics



Leave a reply



Submit