Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uninstall (remove) R package with dependencies

Tags:

r

I wanted to try some new package. I installed it, it required a lot of dependencies, so it installed plenty of other packages. I tried it and I am not impressed - now I would like to uninstall that package including all the dependencies!

Is there any way to remove given packages including all dependencies which are not needed by any other package in the system?

I looked at ?remove.packages but there is no option to do this.

like image 809
Tomas Avatar asked Oct 26 '14 13:10

Tomas


People also ask

How do I completely remove an R package?

Remove a package with remove. packages() e.g. Affycoretools is a Bioconductor pacakge, so reinstallation needs their install script / the BiocInstaller package e.g. Go to the Packages in right bottom corner of Rstudio, sear the package name and click on the adjacent X icon to remove it.

How do I uninstall a package without removing dependencies?

The first “rpm -qa” lists all RPM packages and the grep finds the package you want to remove. Then you copy the entire name and run the “rpm -e –nodeps” command on that package. It will, without prompting for confirmation, remove that package but none of its dependencies.

How do I remove a package from dependencies?

To remove a dev dependency, you need to attach the -D or --save-dev flag to the npm uninstall, and then specify the name of the package. You must run the command in the directory (folder) where the dependency is located.


3 Answers

Here is some code that will all you to remove a package and its unneeded dependencies. Note that its interpretation of "unneeded" dependent packages is the set of packages that this package depends on but that are not used in any other package. This means that it will also default to suggesting to uninstall packages that have no reverse dependencies. Thus I've implemented it as an interactive menu (like in update.packages) to give you control over what to uninstall.

library("tools")

removeDepends <- function(pkg, recursive = FALSE){
    d <- package_dependencies(,installed.packages(), recursive = recursive)
    depends <- if(!is.null(d[[pkg]])) d[[pkg]] else character()
    needed <- unique(unlist(d[!names(d) %in% c(pkg,depends)]))
    toRemove <- depends[!depends %in% needed]
    if(length(toRemove)){
         toRemove <- select.list(c(pkg,sort(toRemove)), multiple = TRUE,
                                 title = "Select packages to remove")
         remove.packages(toRemove)
         return(toRemove)
    } else {
        invisible(character())
    }
}

# Example
install.packages("YplantQMC") # installs an unneeded dependency "LeafAngle"
c("YplantQMC","LeafAngle") %in% installed.packages()[,1]
## [1] TRUE TRUE
removeDepends("YplantQMC")
c("YplantQMC","LeafAngle")  %in% installed.packages()[,1]
## [1] FALSE FALSE

Note: The recursive option may be particularly useful. If package dependencies further depend on other unneeded packages, setting recursive = TRUE is vital. If dependencies are shallow (i.e., only one level down the dependency tree), this can be left as FALSE (the default).

like image 120
Thomas Avatar answered Oct 03 '22 07:10

Thomas


There is in fact a function remove.packages() in base R, but it's in the package utils, which you need to load first:

library(utils)
remove.packages()

It's not entirely clear to me how much recursive cleanup this function does.

like image 23
Andrie Avatar answered Oct 03 '22 07:10

Andrie


There are base R ways to handle this but I'm going to recommend a package (I know you're trying to get rid of these). I'm recommending this package for 2 reasons (1) it solves two problems you're having & (2) Dason K. and I are developing this package (full disclosure). This package's value stands in that the functions are easier to remember names that are consistent. It also does some combined operations. Note you could do all of this in base but this question is already pretty localized so thus I'm going to use a tool that makes answering easier.

This package will:

  1. allow you to delete package and dependencies
  2. allow you to install packages in a temporary directory rather than main library

The caveat is that you can't be 100% certain that the package dependency wasn't already there, installed by the user previously. Therefore I would take caution with every step of this solution that you're not deleting things that are of importance. This solution relies on 2 factors (1) pacman (2) file.info. We'll assume that dependencies that were modified within a certain (user defined) threshold of time are indeed unwanted packages. Note the word assume here.

I made this reproducible for the folks at home in that the answer will randomly install a package from CRAN with additional dependencies (this installs a package you do not already have locally with 3 or more dependencies; used random to not single out any package).

Making a reproducible example

library(pacman)

(available <- p_cran())
(randoms <- setdiff(available,  p_lib()))
(mypackages <- p_lib())

ndeps <- 1
while(ndeps < 3) {

    package <- sample(randoms, 1)
    deps <- unlist(p_depends(package, character.only=TRUE), use.names=FALSE)
    ndeps <- length(setdiff(deps,  mypackages))

}  

package
p_install(package, character.only = TRUE)

Uninstalling package

We will assign the package name from the first part to package or the OP can use the unwanted package they installed and assign that to package (my random package happened to be package <- "OrdinalLogisticBiplot"). This deletions process should, ideally, be done in a clean R session with no add-on packages (except pacman) loaded.

## function to grab file info date/time modified
infograb <- function(x) file.info(file.path(p_path(), x))[["mtime"]]

## determine the differences in times modified for "package" 
## and all other packages in library
diffs <- as.numeric(infograb(package)) -  sapply(p_lib(), infograb)

## user defined threshold
threshold <- 15

## determine packages just installed within the time frame of the unwanted package 
(delete_deps <- diffs[diffs < threshold & diffs >= 0])

## recursively find all packages that could have been installed 
potential_depends <- unlist(lapply(unlist(p_depends(package, character=TRUE)), 
    p_depends, character=TRUE, recursive=TRUE))

## delete packages that are both on the lists of (1) installed within time
## frame of unwanted package and a dependency of that package
p_delete(intersect(names(delete_deps), potential_depends), character.only = TRUE)

This approach makes some big assumptions.

A better approach from the get go

p_temp(package_to_try)

This allows you to try it out first and not have it muddy your local library.

If you're unimpressed with pacman you can use the method described above to delete it.

like image 36
Tyler Rinker Avatar answered Oct 03 '22 05:10

Tyler Rinker