Подтвердить что ты не робот

Удалить (удалить) пакет R с зависимостями

Я хотел попробовать новый пакет. Я установил его, он потребовал много зависимостей, поэтому он установил множество других пакетов. Я попробовал, и я не впечатлен - теперь я хочу удалить этот пакет, включая все зависимости!

Есть ли способ удалить указанные пакеты, включая все зависимости, которые не нужны никакому другому пакету в системе?

Я посмотрел на ?remove.packages, но нет возможности сделать это.

4b9b3361

Ответ 1

Вот код, который позволит вам удалить пакет и его ненужные зависимости. Обратите внимание, что его интерпретация "ненужных" зависимых пакетов - это набор пакетов, от которых зависит этот пакет, но которые не используются ни в одном другом пакете. Это означает, что он также по умолчанию предложит удалить пакеты, которые не имеют обратных зависимостей. Таким образом, я реализовал его как интерактивное меню (например, в update.packages), чтобы дать вам контроль над тем, что нужно удалить.

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

Примечание. Опция recursive может быть особенно полезна. Если зависимости пакета зависят от других ненужных пакетов, установка recursive = TRUE имеет жизненно важное значение. Если зависимости неглубокие (т.е. Только один уровень вниз по дереву зависимостей), это можно оставить как FALSE (по умолчанию).

Ответ 2

В базе R есть функция remove.packages(), но она находится в пакете utils, который вам нужно сначала загрузить:

library(utils)
remove.packages()

Мне не совсем понятно, сколько рекурсивной очистки эта функция делает.

Ответ 3

Есть способы base R обработать это, но я собираюсь рекомендовать пакет (я знаю, что вы пытаетесь избавиться от них). Я рекомендую этот пакет по двум причинам (1) он решает две проблемы, которые у вас есть, и (2) Мы с Дэсоном К. разрабатываем этот пакет (полное раскрытие). Это значение пакета означает, что функции легче запоминать согласованные имена. Он также выполняет некоторые комбинированные операции. Обратите внимание, что вы можете сделать все это в базе, но этот вопрос уже довольно локализован, поэтому я собираюсь использовать инструмент, который облегчает ответ.

Этот пакет будет:

  • позволяет вам удалять пакеты и зависимости
  • позволяют устанавливать пакеты во временном каталоге, а не в основной библиотеке

Предостережение заключается в том, что вы не можете быть на 100% уверены, что зависимость пакета еще не была установлена ​​пользователем ранее. Поэтому я должен проявлять осторожность с каждым шагом этого решения, чтобы вы не удаляли вещи, которые имеют важное значение. Это решение основывается на 2 факторах (1) pacman (2) file.info. Мы будем предполагать, что зависимости, которые были изменены в течение определенного (определенного пользователем) порога времени, действительно являются нежелательными пакетами. Обратите внимание на это слово.

Я сделал это воспроизводимым для людей дома, потому что ответ будет случайным образом устанавливать пакет из CRAN с дополнительными зависимостями (это устанавливает пакет, который у вас еще нет локально с 3 или более зависимостями; используется случайное, чтобы не выделять никаких пакет).

Создание воспроизводимого примера

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)

Удаление пакета

Мы назначим имя пакета из первой части package или OP может использовать установленный им нежелательный пакет и назначить его package (мой случайный пакет оказался package <- "OrdinalLogisticBiplot"). Этот процесс удаления, в идеале, должен выполняться в чистом сеансе R без добавления дополнительных пакетов (кроме pacman).

## 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)

Этот подход делает некоторые большие предположения.

Лучший подход от get go

p_temp(package_to_try)

Это позволяет вам попробовать сначала, а не использовать эту локальную библиотеку.

Если вы не впечатлены с помощью pacman, вы можете использовать описанный выше метод, чтобы удалить его.