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 theused.packages
; - if using RStudio and wanting to apply this to multiple scripts, using
rstudioapi::getSourceEditorContext()$path
instead of"thisfile.R"
inNCmisc::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 oflibrary()
orrequire()
), 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
renv::init()
renv::settings$snapshot.type("all") # if you want to list all
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:
When you see an error, run
traceback()
and look at the stack of function calls; it'll take some sleuthing, but find where thatwday
is being called, find that function in the packages (both exported and internal functions!), and go from there.If all packages are being thorough in announcing packages they import (via
Depends:
,Imports:
, or perhaps even a mis-usedSuggests:
), 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
Replacing the Duplicate Values Except 1 Row in R Dataframe
"Un-Register" a Doparallel Cluster
Clustering List for Hclust Function
Controlling the 'Alpha' Level in a Ggplot2 Legend
How to Plot a Subset of a Data Frame in R
Control Alignment of Two Side-By-Side Plots in Knitr
How to Remove the Legend Title in Ggplot2
R: Count Unique Values by Category
How to Produce Time Series for Each Row of a Data Frame with an Unnamed First Column
Aggregation Using Ffdfdply Function in R
How to Get Rstudio to Automatically Compile R Markdown Vignettes
Difference Between As.Data.Frame(X) and Data.Frame(X)
How to Convert Utm Coordinates to Lat and Long in R
What's the Difference Between Hex Code (\X) and Unicode (\U) Chars
Plot Every Column in a Data Frame as a Histogram on One Page Using Ggplot