Элегантный способ проверить отсутствующие пакеты и установить их? - PullRequest
288 голосов
/ 03 ноября 2010

Кажется, я делюсь большим количеством кода с соавторами в эти дни. Многие из них являются новичками / пользователями среднего уровня и не понимают, что им нужно устанавливать пакеты, которых у них еще нет.

Существует ли элегантный способ вызова installed.packages(), сравните его с теми, которые я загружаю и устанавливаю в случае отсутствия?

Ответы [ 26 ]

4 голосов
/ 17 мая 2015

Следующая простая функция работает как брелок:

  usePackage<-function(p){
      # load a package if installed, else load after installation.
      # Args:
      #   p: package name in quotes

      if (!is.element(p, installed.packages()[,1])){
        print(paste('Package:',p,'Not found, Installing Now...'))
        install.packages(p, dep = TRUE)}
      print(paste('Loading Package :',p))
      require(p, character.only = TRUE)  
    }

(не мой, нашел это в сети некоторое время назад и использовал его с тех пор. Не уверен в первоначальном источнике)

4 голосов
/ 25 июля 2015

Я использую следующую функцию для установки пакета, если require("<package>") завершает работу с ошибкой пакета не найдена. Он запросит оба хранилища - CRAN и Bioconductor на предмет отсутствия пакета.

Адаптировано из оригинальной работы Джошуа Уайли, http://r.789695.n4.nabble.com/Install-package-automatically-if-not-there-td2267532.html

install.packages.auto <- function(x) { 
  x <- as.character(substitute(x)) 
  if(isTRUE(x %in% .packages(all.available=TRUE))) { 
    eval(parse(text = sprintf("require(\"%s\")", x)))
  } else { 
    #update.packages(ask= FALSE) #update installed packages.
    eval(parse(text = sprintf("install.packages(\"%s\", dependencies = TRUE)", x)))
  }
  if(isTRUE(x %in% .packages(all.available=TRUE))) { 
    eval(parse(text = sprintf("require(\"%s\")", x)))
  } else {
    source("http://bioconductor.org/biocLite.R")
    #biocLite(character(), ask=FALSE) #update installed packages.
    eval(parse(text = sprintf("biocLite(\"%s\")", x)))
    eval(parse(text = sprintf("require(\"%s\")", x)))
  }
}

Пример:

install.packages.auto(qvalue) # from bioconductor
install.packages.auto(rNMF) # from CRAN

PS: update.packages(ask = FALSE) & biocLite(character(), ask=FALSE) обновит все установленные пакеты в системе. Это может занять много времени и рассматривать его как полное обновление R, которое не может быть гарантировано все время!

4 голосов
/ 08 февраля 2016

Вы можете просто использовать функцию setdiff, чтобы получить пакеты, которые не установлены, а затем установить их.В приведенном ниже примере мы проверяем, установлены ли пакеты ggplot2 и Rcpp перед их установкой.

unavailable <- setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages()))
install.packages(unavailable)

В одной строке вышеможно записать как:

install.packages(setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages())))
4 голосов
/ 25 мая 2017

Используйте packrat, чтобы общие библиотеки были точно такими же и не меняли окружение других.

С точки зрения элегантности и наилучшей практики, я думаю, что вы в корне ошибаетесь.пакет packrat был разработан для этих проблем.Он разработан RStudio Хэдли Уикхем.Вместо того, чтобы им приходилось устанавливать зависимости и, возможно, портить кому-то среду, система packrat использует свой собственный каталог и устанавливает все зависимости для своих программ в свои и не затрагивает чью-то среду.

Пакетсистема управления зависимостями для пакетов пакета R.

R может разочаровать.Приходилось ли вам когда-либо использовать метод проб и ошибок, чтобы выяснить, какие R-пакеты вам нужно установить, чтобы заставить работать чужой код, а затем навсегда оставить эти пакеты глобально установленными, потому что теперь вы не уверены, нужны ли они вам??Вы когда-нибудь обновляли пакет, чтобы заставить код в одном из ваших проектов работать, только чтобы обнаружить, что из-за обновленного пакета код в другом проекте перестает работать?

Мы создали пакет для решения этих проблем.Используйте packrat, чтобы сделать ваши проекты R более подробными:

  • Изолированный: установка нового или обновленного пакета для одного проекта не нарушит ваши другие проекты, и наоборот.Это потому, что packrat предоставляет каждому проекту свою собственную библиотеку пакетов.
  • Portable: легко переносить ваши проекты с одного компьютера на другой, даже на разные платформы.Packrat упрощает установку пакетов, от которых зависит ваш проект.
  • Воспроизводимые: Packrat записывает точные версии пакетов, от которых вы зависите, и гарантирует, что именно эти версии будут установлены везде, куда вы идете.

https://rstudio.github.io/packrat/

3 голосов
/ 14 апреля 2015

Я реализовал функцию установки и загрузки необходимых R-пакетов в автоматическом режиме. Надежда может помочь. Вот код:

# Function to Install and Load R Packages
Install_And_Load <- function(Required_Packages)
{
    Remaining_Packages <- Required_Packages[!(Required_Packages %in% installed.packages()[,"Package"])];

    if(length(Remaining_Packages)) 
    {
        install.packages(Remaining_Packages);
    }
    for(package_name in Required_Packages)
    {
        library(package_name,character.only=TRUE,quietly=TRUE);
    }
}

# Specify the list of required packages to be installed and load    
Required_Packages=c("ggplot2", "Rcpp");

# Call the Function
Install_And_Load(Required_Packages);
2 голосов
/ 05 марта 2019

Предстоящая версия RStudio (1.2), уже доступная в качестве предварительного просмотра, будет включать функцию обнаружения отсутствующих пакетов в вызовах library() и require() и предложения пользователю установить их:

Обнаружение отсутствующих пакетов R

Многие R-скрипты открываются с вызовами library() и require() для загрузки пакетов, которые им необходимы для выполнения. Если вы откроете скрипт R, который ссылается на пакеты, которые вы не установили, RStudio предложит установить все необходимые пакеты одним щелчком мыши. Больше не нужно набирать install.packages() несколько раз, пока ошибки не исчезнут!
https://blog.rstudio.com/2018/11/19/rstudio-1-2-preview-the-little-things/

Похоже, это особенно хорошо отвечает первоначальной проблеме ОП:

Многие из них являются начинающими / промежуточными пользователями R и не осознают, что им нужно устанавливать пакеты, которых у них еще нет.

2 голосов
/ 28 августа 2018

Используя семейство lapply и подход анонимных функций, вы можете:

  1. Попытаться присоединить все перечисленные пакеты.
  2. Установить только пропущенные (используя || отложенная оценка).
  3. Попытка снова присоединить те, которые отсутствовали на шаге 1 и были установлены на шаге 2.
  4. Печать окончательного состояния загрузки каждого пакета (TRUE / FALSE).

    req <- substitute(require(x, character.only = TRUE))
    lbs <- c("plyr", "psych", "tm")
    sapply(lbs, function(x) eval(req) || {install.packages(x); eval(req)})
    
    plyr psych    tm 
    TRUE  TRUE  TRUE 
    
2 голосов
/ 11 ноября 2013

Относительно вашей главной цели «установить библиотеки, которых у них еще нет» и независимо от использования «instllaed.packages ()» Следующая функция маскирует исходную функцию require. Он пытается загрузить и проверить указанный пакет «x», если он не установлен, установить его напрямую, включая зависимости; и наконец загрузите это обычно. вы переименовываете имя функции из 'require' в 'library', чтобы сохранить целостность. Единственное ограничение - имена пакетов должны быть заключены в кавычки.

require <- function(x) { 
  if (!base::require(x, character.only = TRUE)) {
  install.packages(x, dep = TRUE) ; 
  base::require(x, character.only = TRUE)
  } 
}

Таким образом, вы можете загрузить и установить пакет по старинке. требуют ("ggplot2") требуют ("Rcpp")

2 голосов
/ 04 февраля 2016

Думал, что я добавлю тот, который использую:

testin <- function(package){if (!package %in% installed.packages())    
install.packages(package)}
testin("packagename")
2 голосов
/ 26 ноября 2015

Довольно простой.

pkgs = c("pacman","data.table")
if(length(new.pkgs <- setdiff(pkgs, rownames(installed.packages())))) install.packages(new.pkgs)
...