Tải nhiều gói cùng một lúc


174

Làm thế nào tôi có thể tải một loạt các gói cùng một lúc mà không cần gõ lại lệnh yêu cầu lặp đi lặp lại? Tôi đã thử ba cách tiếp cận tất cả trong đó sụp đổ và đốt cháy.

Về cơ bản, tôi muốn cung cấp một vectơ tên gói cho một hàm sẽ tải chúng.

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

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

Câu trả lời:


251

Một số hoán vị của các hàm được đề xuất của bạn hoạt động - nhưng chỉ khi bạn chỉ định character.onlyđối số là TRUE. Ví dụ nhanh:

lapply(x, require, character.only = TRUE)

@ Mẹ & daroczig - Tuyệt vời. Đó là một giải pháp sạch hơn. Tôi sẽ để lại cho tôi chỉ cho hậu thế, và cho những gì nó thể hiện về lý do tại sao các nỗ lực của OP không hoạt động.
Josh O'Brien

4
Bạn có thể tận dụng kết hợp một phần ký tự và thoát khỏi lapply (x, yêu cầu, ch = T) hoặc thậm chí lapply (x, yêu cầu, c = T)
Dason

@daroczig Mã này tải các gói nhưng tại sao nó lại đưa ra các thông báo Cảnh báo sau: 1: Trong thư viện (gói, lib.loc = lib.loc, character.only = TRUE, logic.return = TRUE ,: không có gói nào được gọi 'x' 2: Trong if (! load) {: điều kiện có độ dài> 1 và chỉ phần tử đầu tiên sẽ được sử dụng
Anusha

@Anusha: Tôi không có ý tưởng ATM, bạn có gì trong bạn x?
daroczig

23
Hãy thật tốt nếu R :: cơ sở thêm lapplythủ thuật này vào library(). Trở nên tuyệt vời để có thể nói:library(c("plyr", "umx"))
tim

58

Các gói phần mềm cran pacman mà tôi duy trì (tác giả với Dason Kurkiewicz) có thể thực hiện điều này:

Vì vậy, người dùng có thể làm:

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

và nếu gói bị thiếu p_loadsẽ tải xuống từ CRAN hoặc Bioconductor.


7
+1! Tại sao bạn chọn tên ngắn p_load? Một tên mô tả nhiều hơn như load_packageslàm cho ý định của chức năng rõ ràng hơn.
Paul Hiemstra

19
Bởi vì p là viết tắt của gói. Mọi chức năng trong gói hữu ích và được xuất bắt đầu bằng p_. Thêm vào đó, chúng tôi có xu hướng sử dụng thư viện một chút và đó là thêm 7 ký tự. 7 ký tự x ~ 1000000 thời gian sử dụng của hàm x .5 giây mỗi ký tự = 3500000 giây. Đó là 58333,33 phút, 972.222 giờ hoặc 40.50926 ngày trong cuộc đời lập trình viên mà chúng tôi đã trả lại cho họ :-) Trong mọi trường hợp, mục tiêu của chúng tôi là đẩy tới CRAN trước ngày 1 tháng 2
Tyler Rinker

3
Chậm hơn một năm nhưng cuối cùng chúng tôi đã nộp cho CRAN. Nên lên trong vài ngày. @trinker (hoặc tôi) đảm bảo sửa đổi điều này một khi nó được công khai.
Dason

5
@Tyler Tôi biết tôi đến muộn nhiều năm nhưng tôi thấy lý do của bạn về p_tiền tố khá đáng ngờ. Nếu sự căng thẳng là vấn đề, hãy loại bỏ p_hoàn toàn tiền tố. Trên thực tế, việc có các tiền tố như vậy thường không được khuyến khích trong các ngôn ngữ khác vì những lý do chính đáng (tôi đã nói với Hadley rằng chúng giống nhau về sự fct_vô nghĩa của anh ta trong forcats). Điều này đặc biệt đúng vì mục đích sử dụng của gói thứ là với một không gian tên đủ điều kiện ( pacman::).
Konrad Rudolph

5
@TylerRinker Xin lỗi vì đã phản đối vấn đề này, nhưng tôi thực sự nghĩ rằng cộng đồng R đơn giản là sai ở đây, và hầu như mọi ngôn ngữ hiện đại khác đều hiểu đúng: Bạn nói điều này Bảo vệ chống lại xung đột không gian tên. - Nhưng đây là không gian tên dành cho! Các onus trên các nhà văn gói là để giáo dục mọi người sử dụng các gói đúng cách, không để phù hợp với thực tiễn lập trình cẩu thả của họ.
Konrad Rudolph

24

Cái này cần phải dùng mẹo:

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

(Bit chính là argsđối số trong do.call(what, args) phải là một danh sách --- ngay cả khi nó chỉ có một phần tử duy nhất!)


16

Đối với ai đó muốn cài đặt và tải các gói đồng thời, tôi đã xem qua chức năng này từ liên kết này

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

Xin chào tôi đã tạo một tệp R từ đoạn mã đã cho của bạn. Khi tôi chạy tập lệnh đó trên dịch vụ EMR của Amazon, nó cung cấp cho tôi đầu ra như được chỉ định trong URL sau. pastie.org/10402378#3,10-11,13 .
Rubin porwal

9

Một lựa chọn thay thế đến từ gói easypackages. Sau khi cài đặt, bạn có thể tải các gói theo cách trực quan nhất:

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

Gói này cũng bao gồm một chức năng để cài đặt một số gói:

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

Tham khảo tại đây .


Tên hàm khá khó hiểu / nhầm lẫn. Thư viện của hoàng cung, trong librarychức năng, đề cập đến vị trí nơi các gói được cài đặt: thư viện gói . Tải một số gói thông qua librarieskhông có ý nghĩa. Có một chức năng riêng biệt packageslàm một cái gì đó khác chỉ làm cho điều này tồi tệ hơn. Tôi biết đặt tên là một vấn đề khó khăn trong công nghệ phần mềm nhưng thực sự. Những cái tên này đặc biệt xấu.
Konrad Rudolph

2
@KonradRudolph Tôi không đồng ý rằng cái tên này librarieskhông có ý nghĩa gì. Đó là số nhiều của library, và librarytải một gói duy nhất; librariestải một số lượng lớn các gói. Nếu bạn nghĩ librarycó nghĩa là "tải từ thư viện duy nhất của bạn" và mở rộng nó thành libraries"tải từ nhiều thư viện", thì có lẽ nó không trực quan, nhưng đó không phải là ý định; Tôi sẽ khá hạnh phúc với cái tên này libraries.
Jamie S

@JamieS Nhưng nó vẫn (thường) tải từ một thư viện duy nhất. Bạn dường như nhầm lẫn thư viện và gói (mà, công bằng mà nói, đã trở nên phổ biến trong R): Thư viện của R R, như nhận xét trước đây của tôi đã đề cập, đề cập đến vị trí (thư mục / thư mục) nơi các gói R được cài đặt . Trong ví dụ của câu trả lời này, những người khác không phải là thư viện, đó là các gói.
Konrad Rudolph

4

Bạn chỉ có thể sử dụng gói Lubripack và cài đặt gọn gàng các gói mới và sau đó tải tất cả chúng trong một dòng.

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

Đây là đầu ra sau khi bạn chạy mã trên RStudio.

nhập mô tả hình ảnh ở đây

Cách cài đặt Gói:

Chạy mã bên dưới để tải gói và cài đặt nó từ GitHub. Không cần phải có Tài khoản GitHub.

library(devtools)
install_github("espanta/lubripack")

5
Tôi đoán là sử dụng hình ảnh thay vì văn bản
Con mèo bất khuất

3
Điều này cũng không trả lời câu hỏi theo cách chưa được trả lời và dường như chủ yếu là tự quảng cáo.
Tyler Rinker

Bạn nói đúng, tôi đã cố gắng trả lời ngầm câu hỏi. Hãy làm cho nó rõ ràng hy vọng nó có thể được trả lời cho câu hỏi.
Espanta

@TylerRinker Làm thế nào bây giờ?
Espanta

3

Dựa trên giải pháp của daroczig, nếu bạn không muốn chỉ định danh sách làm đầu vào, bạn có thể sử dụng

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

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

... ngắn hơn

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

2

Tôi sử dụng chức năng sau:

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

Điều này cố gắng tải, và nếu nó không cài đặt và sau đó thử tải lại.


2

Tôi nghĩ rằng mã mà @daroczig đã cung cấp có thể được cải thiện bằng cách thay thế requirebằng libraryvà gói lapplycuộc gọi bên trong invisible()hàm. Vì vậy, mã được cải tiến sẽ trông như sau:

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

Mã này được cải thiện vì:

  1. library()thường được ưu tiên hơn require()cho việc tải các gói vì cái trước đưa ra lỗi nếu gói không được cài đặt trong khi gói sau chỉ đưa ra cảnh báo. Hơn nữa, require()các cuộc gọi library(), vậy tại sao không chỉ sử dụng library()trực tiếp!

    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. Đối tượng danh sách được trả về và in bởi lapply()cuộc gọi không có ý nghĩa trong trường hợp này, vì vậy nó có ý nghĩa để làm cho đầu ra vô hình. Giả sử bạn sử dụng R Notebook cho công việc phân tích của mình, sử dụng invisible()chức năng sẽ triệt tiêu nội dung của đối tượng danh sách và ngăn chặn sự lộn xộn trong tệp sổ ghi chép được hiển thị.


1

Bản mod nhẹ của câu trả lời của Tyler Rinker để thêm một kiểm tra để cài đặt và tải pacman:

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

Tôi thích giải pháp p_load vì nó tránh được trích dẫn!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.