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

174

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

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

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

require(x)
lapply(x, require)
do.call("require", x)
Тайлер Ринкер
источник

Ответы:

251

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

lapply(x, require, character.only = TRUE)
daroczig
источник
@Tommy & daroczig - Круто. Это гораздо более чистое решение. Я оставлю свой только для потомков и для того, что показывает, почему попытки ОП не сработали.
Джош О'Брайен
4
Вы можете воспользоваться преимуществом частичного сопоставления символов и использовать lapply (x, require, ch = T) или даже lapply (x, require, c = T)
Dason
@daroczig Этот код загружает пакеты, но почему он выдает следующие предупреждающие сообщения: 1: В библиотеке (package, lib.loc = lib.loc, character.only = TRUE, logic.return = TRUE,: пакет не называется 'x' 2: In, если (! загружен) {: условие имеет длину> 1, и будет использоваться только первый элемент
Anusha
@Anusha: Я понятия не имею, банкомат, что у вас есть x?
Дарочи
23
Было бы хорошо, если бы R :: base добавил этот lapplyтрюк к library(). Будьте велики, чтобы иметь возможность сказать:library(c("plyr", "umx"))
Тим
58

CRAN пакет pacman , что я поддерживаю ( в соавторстве с Dason Kurkiewicz) может сделать это:

Таким образом, пользователь может сделать:

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

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

Тайлер Ринкер
источник
7
+1! Почему вы выбрали короткое имя p_load? Более описательное имя, например, load_packagesделает назначение функции более понятным.
Пол Химстра
19
Потому что р обозначает пакет. Каждая функция в пакете, которая полезна и экспортируется, начинается с p_. Плюс мы склонны немного использовать библиотеку, и это дополнительные 7 символов. 7 символов x ~ 1000000 пожизненного использования функции x .5 секунд на символ = 3500000 секунд. Это 58333,33 минуты, 972,2222 часа или 40,50926 дней из жизни программиста, которые мы им вернули :-) В любом случае наша цель - перейти к CRAN к 1 февраля
Тайлер Ринкер
3
Примерно на год позже, но мы наконец-то представились в CRAN Должно быть через несколько дней. @trinker (или я) не забудьте изменить это, как только оно станет общедоступным.
Дейсон
5
@ Тайлер Я знаю, что опоздал на несколько лет, но я считаю p_сомнительным ваше обоснование префикса. Если краткость является проблемой, удалите p_префикс полностью. Фактически, наличие таких префиксов обычно не рекомендуется на других языках по уважительным причинам (я сказал Хэдли, что они одинаковы в отношении его fct_глупости в forcats). Это особенно верно, поскольку предполагаемое использование th-пакета с квалифицированным пространством имен ( pacman::).
Конрад Рудольф
5
@TylerRinker Прошу прощения за боевые действия в этом вопросе, но я действительно считаю, что сообщество R просто ошибается здесь, и практически любой другой современный язык понимает это правильно: вы говорите: «Это защищает от конфликтов пространства имен». - Но это то, что пространства имен для! Авторы пакетов должны научить людей правильно использовать пакеты, а не приспосабливаться к их неаккуратным практикам программирования.
Конрад Рудольф
24

Это должно сделать трюк:

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

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

Джош О'Брайен
источник
16

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

# 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)
бала
источник
Здравствуйте, я создал файл R из вашего данного фрагмента. Когда я запускаю этот скрипт в сервисе Amazon EMR, он выдает мне следующий вывод, как указано в следующем URL. pastie.org/10402378#3,10-11,13 .
Рубин Porwal
9

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

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

В пакет также входит функция для установки нескольких пакетов:

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

Ссылка здесь .

luchonacho
источник
Название функции довольно запутанное / запутанное. «Библиотека» в libraryфункции относится к месту, где установлены пакеты: библиотека пакетов . Загрузка нескольких пакетов через librariesнет смысла. Наличие отдельной функции, packagesкоторая делает что-то еще, только ухудшает это. Я знаю, что именование - сложная проблема в разработке программного обеспечения, но на самом деле. Эти имена особенно плохи.
Конрад Рудольф
2
@KonradRudolph Я не согласен, что название librariesне имеет смысла. Это множественное число libraryи libraryзагружает один пакет; librariesзагружает множество пакетов. Если вы понимаете, что libraryозначает «загрузить из вашей отдельной библиотеки», и расширили это librariesзначение до «загрузки из нескольких библиотек», то это, возможно, не интуитивно понятно, но это не цель; Я был бы вполне доволен именем libraries.
Джейми С
@JamieS Но он все еще (обычно) загружается из одной библиотеки. Вы, кажется, путаете библиотеку и пакет (что, честно говоря, стало обычным в R): «Библиотека R», как говорилось в моем предыдущем комментарии, относится к местоположению (ям) (каталог / каталоги), где установлены пакеты R , В этом примере ответа «plyr», «psych» и «tm» не являются библиотеками: они являются пакетами.
Конрад Рудольф
4

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

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

Вот вывод после запуска кода выше в RStudio.

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

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

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

library(devtools)
install_github("espanta/lubripack")
Espanta
источник
5
Я бы предположил, используя изображения вместо текста
The Unfun Cat
3
Это также не отвечает на вопрос так, как на него еще не ответили, и кажется, что это в основном самореклама.
Тайлер Ринкер
Вы правы, я попытался безоговорочно ответить на вопрос. Давайте сделаем это явно, надеясь, что это может быть ответом на вопрос.
Espanta
@TylerRinker Как это сейчас?
Espanta
3

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

# 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)
goclem
источник
2

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

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

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

Рикарду
источник
2

Я думаю, что код, предоставленный @daroczig, можно улучшить, заменив оператор requirewith 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()функцию, чтобы подавить содержимое объекта списка и предотвратить беспорядок в визуализированном файле ноутбука.

Ashirwad
источник
1

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

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

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

mattador
источник