Загрузить несколько пакетов одновременно

Как я могу загрузить сразу несколько пакетов, не вводя команду require снова и снова? Я испробовал три подхода, все из которых вылетали и горели.

По сути, я хочу предоставить вектор имен пакетов функции, которая их загрузит.

x<-c("plyr", "psych", "tm")

require(x)
lapply(x, require)
do.call("require", x)

person Tyler Rinker    schedule 17.11.2011    source источник


Ответы (10)


Несколько вариантов предложенных вами функций действительно работают, но только если вы укажете аргумент character.only равным TRUE. Быстрый пример:

lapply(x, require, character.only = TRUE)
person daroczig    schedule 17.11.2011
comment
@Tommy & daroczig - Круто. Это гораздо более чистое решение. Я оставлю свой только для потомков и для того, что он показывает, почему попытки ОП не сработали. - person Josh O'Brien; 18.11.2011
comment
Вы можете воспользоваться преимуществом частичного сопоставления символов и уйти с lapply (x, require, ch = T) или даже lapply (x, require, c = T) - person Dason; 18.11.2011
comment
@daroczig Этот код загружает пакеты, но почему он выдает следующие предупреждающие сообщения: 1: В библиотеке (package, lib.loc = lib.loc, character.only = TRUE, logic.return = TRUE,: пакет не вызван 'x' 2: В if (! loaded) {: длина условия ›1 и будет использоваться только первый элемент - person Anusha; 01.11.2012
comment
@ Ануша: Понятия не имею, банкомат, что у тебя в x? - person daroczig; 01.11.2012
comment
@daroczig Я просто использую приведенный здесь код. Команда do.call изменена на do.call (require, list (x)), иначе она не будет работать. Если это поможет, используйте rstudio. - person Anusha; 01.11.2012
comment
@Anusha: Я должен пропустить что-то очевидное, но я никогда не набирал do.call в своем ответе, поэтому я немного озадачен вашим ответом. - person daroczig; 01.11.2012
comment
@daroczig Извините. Я думал, вы добавляете character.only = T к указанному коду. И следующий ответ Джоша также включал команду do.call. Может быть, правка прояснит для других читателей. - person Anusha; 01.11.2012
comment
@daroczig: можно ли это расширить, добавив вызов установки любых отсутствующих пакетов из списка, предоставленного x? - person Paulo E. Cardoso; 19.02.2013
comment
@PauloCardoso: конечно, но это может быть больше, чем однострочный :) В основном вы должны проверить возвращаемое значение require и запустить install.packages, если это приведет к FALSE и снова require. Пожалуйста, откройте новый вопрос (и, возможно, ссылку здесь), если вы застрянете. - person daroczig; 19.02.2013
comment
@daroczig: спасибо. Я думаю, это сработает: new.packs ‹- packs [! (Packs% in% installed.packages () [, Package])] if (length (new.packs)) install.packages (new.packs) lapply (new.packages, require, character.only = T). Объединение вашего примера и примера Шейна из здесь < / а> - person Paulo E. Cardoso; 20.02.2013
comment
@PauloCardoso: верно. Хотя я бы предпочел что-то вроде lapply(x, function(x) {if (!require(x, character.only=T)) {install.packages(x);require(x)}}), чтобы сохранить все предыдущие проверки и выполнять установку только по запросу. Если мы укажем список пакетов для загрузки (и установки, если необходимо) символом x - точно так же, как запросил OP. Но это уже довольно долго, чтобы развивать это в комментариях :) - person daroczig; 20.02.2013
comment
Будьте любезны, если R :: base добавит этот lapply трюк, свойственный library(). Будьте счастливы, если сможете сказать: library(c("plyr", "umx")) - person tim; 28.06.2015

Пакет CRAN pacman, который я поддерживаю (созданный вместе с Дэйсоном Куркевичем), может сделать это:

Итак, пользователь мог:

## install.packages("pacman")
pacman::p_load(dplyr, psych, tm) 

и если пакет отсутствует, p_load загрузит его с CRAN или Bioconductor.

person Tyler Rinker    schedule 22.03.2013
comment
+1! Почему вы выбрали короткое имя p_load? Более описательное имя, такое как load_packages, делает назначение функции более ясным. - person Paul Hiemstra; 12.01.2014
comment
Поскольку p означает пакет. Каждая полезная и экспортируемая функция в пакете начинается с p_. Кроме того, мы склонны немного использовать библиотеку, а это еще 7 символов. 7 символов x ~ 1000000 время жизни использования функции x 0,5 секунды на символ = 3500000 секунд. Это 58333,33 минуты, 972,2222 часа или 40,50926 дней жизни программиста, которые мы им вернули :-) В любом случае наша цель - перейти на CRAN к 1 февраля. - person Tyler Rinker; 12.01.2014
comment
Примерно на год позже, но мы наконец отправились в CRAN. Должно быть через несколько дней. @trinker (или я) обязательно измените его, когда он станет общедоступным. - person Dason; 15.02.2015
comment
@Tyler Я знаю, что опоздал на много лет, но я считаю, что ваше объяснение префикса p_ довольно сомнительно. Если проблема заключается в краткости, полностью удалите префикс p_. Фактически, использование таких префиксов в других языках обычно не приветствуется по уважительным причинам (я сказал Хэдли, что они такие же в отношении его fct_ ерунды в forcats). Это особенно верно, поскольку предполагаемое использование этого пакета связано с квалифицированным пространством имен (pacman::). - person Konrad Rudolph; 23.02.2017
comment
@KonradRudolph Я вижу суть, но в обычных пакетах R уже есть много функций, включая базовые пакеты с этими именами. Это защищает от конфликтов пространства имен. Вы указываете, что я использую pacman::, но глупо полагать, что все будут использовать пакет так, как я. Как и в большинстве случаев, здесь есть компромисс. Здесь компромисс между лаконичностью и информативностью и конфликтами пространств имен. К тому же на данном этапе подобное изменение сломало бы код слишком многих людей. - person Tyler Rinker; 23.02.2017
comment
@TylerRinker Приносим извинения за воинственность в этом вопросе, но я действительно считаю, что сообщество R здесь просто ошибается, и практически любой другой современный язык понимает это правильно: вы говорите: «Это защищает от конфликтов пространств имен». - Но пространства имен предназначены для этого! Задача авторов пакетов - научить людей правильно пользоваться пакетами, а не приспосабливаться к их небрежным методам программирования. - person Konrad Rudolph; 23.02.2017
comment
Прохладный! Думаю, это решает вопросы stackoverflow.com/q/9341635/1169233 и stackoverflow.com/q/4090169/1169233 (я вижу, вы отправили ответ на последнее, но не на первое, которое все равно закрыто). - person Waldir Leoncio; 08.02.2018
comment
@TylerRinker, большое спасибо за удобное решение - есть ли еще способ использовать p_load() в строковом векторе пакетов, скажем pks <- c("devtools", "tidyverse")? - person Ivo; 12.11.2019
comment
@Ivo character.only = TRUE или p_load(char = pks) - person Tyler Rinker; 12.11.2019
comment
Этот подход от Митчелла О'Хара-Уайлда Полезно - person p0bs; 28.06.2021

Это должно помочь:

lapply(x, FUN = function(X) {
    do.call("require", list(X)) 
})

(Ключевой бит заключается в том, что аргумент args в do.call(what, args) должен быть списком - даже если он содержит только один элемент!)

person Josh O'Brien    schedule 17.11.2011

Для тех, кто хочет устанавливать и загружать пакеты одновременно, я наткнулся на эту функцию по этой ссылке

# ipak function: install and load multiple R packages.
# check to see if packages are installed. Install them if they are not, then load them into the R session.

ipak <- function(pkg){
new.pkg <- pkg[!(pkg %in% installed.packages()[, "Package"])]
if (length(new.pkg)) 
    install.packages(new.pkg, dependencies = TRUE)
sapply(pkg, require, character.only = TRUE)
}

# usage
packages <- c("ggplot2", "plyr", "reshape2", "RColorBrewer", "scales", "grid")
ipak(packages)
person bala    schedule 12.06.2014
comment
Здравствуйте, я создал R-файл из вашего фрагмента. Когда я запускаю этот скрипт в сервисе Amazon EMR, он дает мне следующий вывод, указанный в следующем URL-адресе. pastie.org/10402378#3,10-11,13. - person Rubin Porwal; 07.09.2015

Альтернативный вариант - из пакета easypackages. После установки вы можете загружать пакеты наиболее интуитивно понятным способом:

libraries("plyr", "psych", "tm")

Пакет также включает функцию установки нескольких пакетов:

packages("plyr", "psych", "tm")

См. здесь.

person luchonacho    schedule 01.12.2016
comment
Название функции довольно запутанное / запутанное. «Библиотека» в функции library относится к месту, где установлены пакеты: библиотека пакетов. Загружать несколько пакетов через libraries не имеет смысла. Наличие отдельной функции packages, которая делает что-то еще, только усугубляет ситуацию. Я знаю, что именование - сложная проблема в разработке программного обеспечения, но на самом деле. Эти имена особенно плохи. - person Konrad Rudolph; 23.02.2017
comment
@KonradRudolph Я не согласен с тем, что имя libraries не имеет смысла. Это множественное число от library, а library загружает один пакет; libraries загружает множество пакетов. Если вы думаете о library как о значении загрузки из вашей единственной библиотеки и расширяете это до libraries, что означает загрузку из нескольких библиотек, то это, возможно, не интуитивно понятно, но это не цель; Я был бы вполне доволен названием libraries. - person Jamie S; 03.10.2018
comment
@JamieS Но это все еще (обычно) загрузка из одной библиотеки. Кажется, вы путаете библиотеку и пакет (что, честно говоря, стало обычным явлением в R): «Библиотека R», как было сказано в моем предыдущем комментарии, относится к местоположению (ям) (каталог / каталоги), где установлены пакеты R . В примере этого ответа «plyr», «mental» и «tm» являются не библиотеками: это пакеты. - person Konrad Rudolph; 04.10.2018

Я думаю, что код, предоставленный @daroczig, можно улучшить, заменив require на library и заключив вызов lapply в функцию invisible(). Итак, улучшенный код будет выглядеть следующим образом:

invisible(lapply(x, library, character.only = TRUE))

Этот код улучшен, потому что:

  1. library() обычно предпочтительнее require() для загрузки пакетов, потому что первый выдает ошибку, если пакет не установлен, а второй просто выдает предупреждение. Более того, require() вызывает library(), так почему бы просто не использовать library() напрямую!

    library("time")
    # Error in library("time") : there is no package called ‘time’
    
    require("time")
    # Loading required package: time
    # Warning message:
    # In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE,  :
    # there is no package called ‘time’
    
  2. Объект списка, возвращаемый и выводимый вызовом lapply(), не имеет смысла в этом случае, поэтому имеет смысл сделать вывод невидимым. Предположим, вы используете R Notebook для своей аналитической работы, использование функции invisible() подавит содержимое объекта списка и предотвратит беспорядок в визуализированном файле записной книжки.

person Ashirwad    schedule 18.04.2019

Вы можете просто использовать пакет lubripack, и он аккуратно устанавливает новые пакеты, а затем загружает их все в одну строку.

lubripack("plyr", "psych", "tm")

Вот результат выполнения кода выше в RStudio.

введите здесь описание изображения

Как установить пакет:

Запустите приведенный ниже код, чтобы загрузить пакет и установить его с GitHub. Нет необходимости иметь учетную запись GitHub.

library(devtools)
install_github("espanta/lubripack")
person Espanta    schedule 23.04.2016
comment
Я бы предположил, что использовал изображения вместо текста - person The Unfun Cat; 03.05.2016
comment
Это также не дает ответа на вопрос, на который еще не ответили, и, по-видимому, в основном является саморекламой. - person Tyler Rinker; 09.05.2016
comment
Вы правы, я попытался беспрекословно ответить на вопрос. Давайте сделаем это явным, надеясь, что это может быть ответ на вопрос. - person Espanta; 18.05.2016
comment
@TylerRinker Как это сейчас? - person Espanta; 18.05.2016

Основываясь на решении daroczig, если вы не хотите указывать список в качестве входных данных, вы можете использовать

# Foo
mLoad <- function(...) {
  sapply(sapply(match.call(), as.character)[-1], require, character.only = TRUE)
}

# Example 
mLoad(plyr, dplyr, data.table)

... что короче, чем

lapply(list('plyr', 'dplyr', 'data.table'), require, character.only = TRUE)
person goclem    schedule 19.11.2015

Я использую следующую функцию:

mrip <- function(..., install = TRUE){
    reqFun <- function(pack) {
        if(!suppressWarnings(suppressMessages(require(pack, character.only = TRUE)))) {
            message(paste0("unable to load package ", pack,
                           ": attempting to download & then load"))
            install.packages(pack)
            require(pack, character.only = TRUE)
        }
    }
    lapply(..., reqFun)
}

Это пытается загрузиться, и, если это не удается, устанавливает, а затем пытается загрузить снова.

person ricardo    schedule 12.01.2014

Небольшая модификация ответа Тайлера Ринкера, чтобы добавить проверку для установки и загрузки pacman:

#Install/load pacman
if(!require(pacman)){install.packages("pacman");require(pacman)}
#Install/load tons of packages
p_load(plyr,psych,tm)

Мне нравится решение p_load, потому что оно избегает цитирования!

person mattador    schedule 17.06.2019