Cách thanh lịch để kiểm tra các gói bị thiếu và cài đặt chúng?


336

Tôi dường như đang chia sẻ rất nhiều mã với các đồng tác giả những ngày này. Nhiều người trong số họ là người dùng R mới làm quen / trung cấp và không nhận ra rằng họ phải cài đặt các gói họ chưa có.

Có một cách thanh lịch để gọi installed.packages(), so sánh với những cách tôi đang tải và cài đặt nếu thiếu?


1
@krlmlr Điều gì về câu trả lời được chấp nhận đã hết hạn và yêu cầu sửa đổi? Nó hoạt động cho tôi (cho một vài thử nghiệm nhanh) dưới R version 3.0.2 (2013-09-25) x86_64-w64-mingw32/x64 (64-bit).
Brian Diggs

1
@BrianDiggs: Ít nhất ba gói đã xuất hiện giải quyết vấn đề này, chỉ có một gói được tham chiếu bên dưới. Có nhiều hơn nữa - đó là câu hỏi.
krlmlr

2
@krlmlr Dường như có một chút vấn đề mỉa mai gà về việc sử dụng một gói để đảm bảo (những người khác) có các gói cần thiết. Nhưng chắc chắn có giá trị khi có người biết về họ viết ra một câu trả lời.
Brian Diggs

2
@BrianDiggs: Bootstrapping gói kiểm tra cài đặt này là một phiền toái cần thiết, nhưng là một vấn đề nhỏ. Tất nhiên, trừ khi chức năng tìm đường vào base... ;-)
krlmlr

Câu trả lời:


303

Đúng. Nếu bạn có danh sách các gói, hãy so sánh nó với đầu ra từ installed.packages()[,"Package"]và cài đặt các gói còn thiếu. Một cái gì đó như thế này:

list.of.packages <- c("ggplot2", "Rcpp")
new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(new.packages)

Nếu không thì:

Nếu bạn đặt mã của mình vào một gói và làm cho chúng phụ thuộc, thì chúng sẽ tự động được cài đặt khi bạn cài đặt gói của mình.


11
Tôi nghĩ cú pháp thích hợp là: if(length(new.packages)>0) {install.packages(new.packages)}

5
@psql, Shine là đúng, vì "> 0" là "ẩn" trong điều kiện if. chạy cái này để xác minh nó:new.packages <- c(1,2) length(new.packages) if(length(new.packages)){print("hello!")}else{print("oh no!")}
Andrea Cirillo

7
Tài liệu của tệp install.packages nêu rõ: "Điều này có thể chậm khi hàng nghìn gói được cài đặt, vì vậy đừng sử dụng gói này để tìm hiểu xem gói đã đặt tên có được cài đặt không (sử dụng system.file hoặc find.package) ..."
Thomas Materna

2
Đồng ý với Thomas, đây sẽ là hiệu suất tốt hơn requirethay vì kiểm trainstalled.packages
Matthew

1
packratđã được thực hiện cho điều này. Nó là một hệ thống quản lý gói tái sản xuất. Cách này đang diễn ra sai cách và gây rối với môi trường của người khác và không thể tái tạo. Packrat có thư mục và môi trường riêng cho các thư viện dùng chung. rstudio.github.io/packrat
mtelesha

231

Dason K. và tôi có gói pacman có thể làm điều này độc đáo. Các chức năng p_loadtrong gói làm điều này. Dòng đầu tiên chỉ để đảm bảo rằng pacman được cài đặt.

if (!require("pacman")) install.packages("pacman")
pacman::p_load(package1, package2, package_n)

1
Tình trạng của gói là gì? Tôi không thể thấy trên C-RAN.
MERose 5/2/2015

4
@Merose pacman hiện đã có trên CRAN cran.r-project.org/web/packages/pacman/index.html
Tyler Rinker

6
Đã cài đặt ngay bây giờ và hoạt động tuyệt vời; nên là một phần của cơ sở!
AndyF

3
Cách duy nhất này sẽ tốt hơn nếu nó được kiểm tra /và, nếu tìm thấy, tự động cài đặt / tải từ github.
cuộc không kích

4
@NealBarsch nếu bạn muốn nói rằng if (!require("pacman")) install.packages("pacman")có một chức năng trong pacman đã gọi p_boot()đó là dòng này cho bạn tự động và sao chép nó vào bảng tạm.
Tyler Rinker

72

Bạn chỉ có thể sử dụng giá trị trả về của require:

if(!require(somepackage)){
    install.packages("somepackage")
    library(somepackage)
}

Tôi sử dụng librarysau khi cài đặt vì nó sẽ đưa ra một ngoại lệ nếu cài đặt không thành công hoặc gói không thể được tải vì một số lý do khác. Bạn làm điều này mạnh mẽ hơn và có thể sử dụng lại:

dynamic_require <- function(package){
  if(eval(parse(text=paste("require(",package,")")))) return True

  install.packages(package)
  return eval(parse(text=paste("require(",package,")")))
}

Nhược điểm của phương pháp này là bạn phải chuyển tên gói trong ngoặc kép, điều mà bạn không làm cho thực tế require.


4
Bạn có thể đơn giản hóa cuộc sống của bạn rất nhiều bằng cách sử dụng character.only = TRUEtrong require, nhưng sau đó tôi đoán không có gì để phân biệt câu trả lời của bạn từ mỏ là.
Simon O'Hanlon

Điều này có vẻ tốt nhưng nó dường như không hoạt động, ít nhất là đối với tôi. Khi tôi dùng thử phiên bản mạnh mẽ này, tôi nhận được hai thông báo lỗi vì R không biết cách xử lý "return True" và "return eval" vì một số lý do. Vì vậy, tôi thực sự muốn một chức năng như thế này tải một gói nếu có trong thư viện của tôi và nếu không thì cài đặt (và sau đó tải) gói. Lý tưởng nhất là sau đó tôi sẽ sử dụng điều này như một mặc định để tải các gói. Ít nhất có vẻ như nó có ý nghĩa để làm như vậy và sẽ tiết kiệm thời gian.
Fabian Habersack

23
if (!require('ggplot2')) install.packages('ggplot2'); library('ggplot2')

"ggplot2" là gói. Nó kiểm tra xem gói đã được cài đặt chưa, nếu không cài đặt. Sau đó nó tải gói bất kể nó lấy chi nhánh nào.


21

Giải pháp này sẽ lấy một vectơ ký tự của tên gói và cố gắng tải chúng hoặc cài đặt chúng nếu tải không thành công. Nó dựa vào hành vi trở lại requiređể làm điều này bởi vì ...

require trả về (vô hình) một logic cho biết liệu gói yêu cầu có sẵn không

Do đó, chúng ta có thể chỉ cần xem liệu chúng ta có thể tải gói cần thiết hay không và nếu không, hãy cài đặt nó với các phụ thuộc. Vì vậy, đưa ra một vectơ ký tự của các gói bạn muốn tải ...

foo <- function(x){
  for( i in x ){
    #  require returns TRUE invisibly if it was able to load package
    if( ! require( i , character.only = TRUE ) ){
      #  If package was not able to be loaded then re-install
      install.packages( i , dependencies = TRUE )
      #  Load package after installing
      require( i , character.only = TRUE )
    }
  }
}

#  Then try/install packages...
foo( c("ggplot2" , "reshape2" , "data.table" ) )

Bạn có muốn gọi requirelại sau khi cài đặt không?
krlmlr

@krlmlr Không, vì ifđể đánh giá câu lệnh, trước tiên nó phải đánh giá require, tác dụng phụ của việc tải gói nếu có sẵn!
Simon O'Hanlon

1
SimonO101: Tôi nghĩ krlmlr có nghĩa là trong câu lệnh if, sau lệnh gọi install.packages, vì điều này sẽ không thực sự tải gói đó. Nhưng (với @krlmlr) Tôi nghi ngờ mục đích là đoạn mã này sẽ chỉ được gọi một lần; bạn sẽ không viết điều này mỗi khi bạn yêu cầu gói. Thay vào đó, bạn sẽ chạy nó một lần trước thời hạn và sau đó gọi requirenhư bình thường khi cần thiết.
Aaron rời Stack Overflow

@Aaron ah vâng ok, tôi hiểu ý của bạn, và vâng, cách giải thích của bạn là đúng. Tôi sẽ chỉnh sửa nó một chút để rõ ràng hơn về việc tải sau khi cài đặt.
Simon O'Hanlon

1
Sẽ không tốt hơn để thực hiện requirecuộc gọi thứ hai để librarynó thất bại một cách ồn ào nếu vẫn không thể đính kèm gói vì lý do nào đó?
kabdulla

18

Rất nhiều câu trả lời ở trên (và trên các bản sao của câu hỏi này) dựa vào installed.packagesđó là hình thức xấu. Từ tài liệu:

Điều này có thể bị chậm khi hàng ngàn gói được cài đặt, vì vậy đừng sử dụng gói này để tìm hiểu xem gói đã được cài đặt chưa (sử dụng system.file hoặc find.package) cũng như để tìm hiểu xem gói có thể sử dụng được không (yêu cầu cuộc gọi và kiểm tra giá trị trả về) cũng như không tìm thấy chi tiết của một số lượng nhỏ các gói (sử dụng gói Mô tả). Nó cần phải đọc một số tệp trên mỗi gói được cài đặt, sẽ chậm trên Windows và trên một số hệ thống tệp được gắn trên mạng.

Vì vậy, cách tiếp cận tốt hơn là thử tải gói bằng cách sử dụng requirevà cài đặt nếu tải không thành công ( requiresẽ trả về FALSEnếu không tìm thấy). Tôi thích thực hiện này:

using<-function(...) {
    libs<-unlist(list(...))
    req<-unlist(lapply(libs,require,character.only=TRUE))
    need<-libs[req==FALSE]
    if(length(need)>0){ 
        install.packages(need)
        lapply(need,require,character.only=TRUE)
    }
}

có thể được sử dụng như thế này:

using("RCurl","ggplot2","jsonlite","magrittr")

Bằng cách này, nó tải tất cả các gói, sau đó quay lại và cài đặt tất cả các gói bị thiếu (nếu bạn muốn, là một nơi thuận tiện để chèn một dấu nhắc để hỏi xem người dùng có muốn cài đặt gói không). Thay vì gọi install.packagesriêng cho từng gói, nó sẽ chuyển toàn bộ véc tơ của các gói đã gỡ cài đặt chỉ một lần.

Đây là chức năng tương tự nhưng với hộp thoại windows hỏi người dùng có muốn cài đặt các gói bị thiếu không

using<-function(...) {
    libs<-unlist(list(...))
    req<-unlist(lapply(libs,require,character.only=TRUE))
    need<-libs[req==FALSE]
    n<-length(need)
    if(n>0){
        libsmsg<-if(n>2) paste(paste(need[1:(n-1)],collapse=", "),",",sep="") else need[1]
        print(libsmsg)
        if(n>1){
            libsmsg<-paste(libsmsg," and ", need[n],sep="")
        }
        libsmsg<-paste("The following packages could not be found: ",libsmsg,"\n\r\n\rInstall missing packages?",collapse="")
        if(winDialog(type = c("yesno"), libsmsg)=="YES"){       
            install.packages(need)
            lapply(need,require,character.only=TRUE)
        }
    }
}

Đây là một cách khá thanh lịch, tốt hơn nhiều so với cách được chấp nhận. Tôi sẽ đưa nó vào thư viện cá nhân của tôi. Cảm ơn.
Bing

15

Mặc dù câu trả lời của Shane thực sự tốt, nhưng đối với một trong những dự án của tôi, tôi cần phải loại bỏ các thông báo, cảnh báo và cài đặt các gói tự động . Cuối cùng tôi đã có được kịch bản này:

InstalledPackage <- function(package) 
{
    available <- suppressMessages(suppressWarnings(sapply(package, require, quietly = TRUE, character.only = TRUE, warn.conflicts = FALSE)))
    missing <- package[!available]
    if (length(missing) > 0) return(FALSE)
    return(TRUE)
}

CRANChoosen <- function()
{
    return(getOption("repos")["CRAN"] != "@CRAN@")
}

UsePackage <- function(package, defaultCRANmirror = "http://cran.at.r-project.org") 
{
    if(!InstalledPackage(package))
    {
        if(!CRANChoosen())
        {       
            chooseCRANmirror()
            if(!CRANChoosen())
            {
                options(repos = c(CRAN = defaultCRANmirror))
            }
        }

        suppressMessages(suppressWarnings(install.packages(package)))
        if(!InstalledPackage(package)) return(FALSE)
    }
    return(TRUE)
}

Sử dụng:

libraries <- c("ReadImages", "ggplot2")
for(library in libraries) 
{ 
    if(!UsePackage(library))
    {
        stop("Error!", library)
    }
}

9
# List of packages for session
.packages = c("ggplot2", "plyr", "rms")

# Install CRAN packages (if not already installed)
.inst <- .packages %in% installed.packages()
if(length(.packages[!.inst]) > 0) install.packages(.packages[!.inst])

# Load packages into session 
lapply(.packages, require, character.only=TRUE)

6

Đây là mục đích của gói rbundler : để cung cấp cách kiểm soát các gói được cài đặt cho một dự án cụ thể. Ngay bây giờ gói hoạt động với chức năng devtools để cài đặt các gói vào thư mục dự án của bạn. Các chức năng tương tự như gói của Ruby .

Nếu dự án của bạn là một gói (được khuyến nghị) thì tất cả những gì bạn phải làm là tải rbundler và gói các gói. Các bundlechức năng sẽ xem xét của gói DESCRIPTIONtập tin để xác định gói để gói.

library(rbundler)
bundle('.', repos="http://cran.us.r-project.org")

Bây giờ các gói sẽ được cài đặt trong thư mục .Rbundle.

Nếu dự án của bạn không phải là một gói, thì bạn có thể giả mạo nó bằng cách tạo một DESCRIPTIONtệp trong thư mục gốc của dự án với trường Phụ thuộc liệt kê các gói bạn muốn cài đặt (với thông tin phiên bản tùy chọn):

Depends: ggplot2 (>= 0.9.2), arm, glmnet

Đây là repo github cho dự án nếu bạn muốn đóng góp: rbundler .


5

Chắc chắn rồi.

Bạn cần so sánh 'các gói đã cài đặt' với 'các gói mong muốn'. Điều đó rất gần với những gì tôi làm với CRANberries khi tôi cần so sánh 'các gói đã biết được lưu trữ' với 'các gói được biết hiện tại' để xác định các gói mới và / hoặc cập nhật.

Vì vậy, làm một cái gì đó như

AP <- available.packages(contrib.url(repos[i,"url"]))   # available t repos[i]

để có được tất cả các gói đã biết, hãy gọi mô phỏng cho các gói hiện được cài đặt và so sánh với các gói mục tiêu đã cho.


5

Sử dụng packratsao cho các thư viện dùng chung giống hệt nhau và không thay đổi môi trường của người khác.

Về mặt thanh lịch và thực hành tốt nhất tôi nghĩ rằng về cơ bản bạn đang đi sai về nó. Gói packratđược thiết kế cho những vấn đề này. Nó được phát triển bởi RStudio bởi Hadley Wickham. Thay vì họ phải cài đặt các phụ thuộc và có thể gây rối hệ thống môi trường của ai đó, hãy packratsử dụng thư mục riêng và cài đặt tất cả các phụ thuộc cho các chương trình của bạn trong đó và không chạm vào môi trường của ai đó.

Packrat là một hệ thống quản lý phụ thuộc cho R.

Phụ thuộc gói R có thể được bực bội. Bạn đã bao giờ phải sử dụng thử và lỗi để tìm ra gói R nào bạn cần cài đặt để làm cho mã của người khác hoạt động và sau đó bị bỏ lại với các gói đó được cài đặt trên toàn cầu mãi mãi, vì bây giờ bạn không chắc liệu bạn có cần chúng không ? Bạn đã bao giờ cập nhật một gói để có được mã trong một trong các dự án của bạn để làm việc, chỉ để thấy rằng gói được cập nhật làm cho mã trong dự án khác ngừng hoạt động?

Chúng tôi xây dựng packrat để giải quyết những vấn đề này. Sử dụng packrat để làm cho các dự án R của bạn nhiều hơn:

  • Bị cô lập: Cài đặt gói mới hoặc cập nhật cho một dự án sẽ không phá vỡ các dự án khác của bạn và ngược lại. Đó là bởi vì packrat cung cấp cho mỗi dự án thư viện gói riêng của mình.
  • Portable: Dễ dàng vận chuyển các dự án của bạn từ máy tính này sang máy tính khác, thậm chí trên các nền tảng khác nhau. Packrat giúp dễ dàng cài đặt các gói mà dự án của bạn phụ thuộc vào.
  • Tái sản xuất: Packrat ghi lại các phiên bản gói chính xác mà bạn phụ thuộc và đảm bảo các phiên bản chính xác đó là phiên bản được cài đặt mọi lúc mọi nơi.

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


4

Các chức năng đơn giản sau đây hoạt động như một nét duyên dáng:

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

(không phải của tôi, đã tìm thấy cái này trên web một thời gian trước và đã sử dụng nó từ đó. Không chắc chắn về nguồn gốc)


4

Tôi sử dụng chức năng sau để cài đặt gói nếu require("<package>")thoát với gói không tìm thấy lỗi. Nó sẽ truy vấn cả hai - kho CRAN và Bioconductor cho gói bị thiếu.

Được chuyển thể từ tác phẩm gốc của Joshua Wiley, 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)))
  }
}

Thí dụ:

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

PS: update.packages(ask = FALSE)& biocLite(character(), ask=FALSE)sẽ cập nhật tất cả các gói đã cài đặt trên hệ thống. Điều này có thể mất nhiều thời gian và coi nó như một bản nâng cấp R đầy đủ có thể không được bảo hành mọi lúc!


Nó có thể được cải thiện bằng cách kiểm tra nếu các gói thực sự có sẵn trên cran hoặc bc. Ngoài ra, nó nên sử dụng thư viện ở cuối để đưa ra lỗi nếu cài đặt không thành công hoặc gói không tồn tại. Xem phiên bản cải tiến của tôi được gọi loadpack()trên raw.githubusercontent.com/holgerbrandl/datautils/master/R/ Kẻ
Holger Brandl

4

Bạn chỉ có thể sử dụng setdiffchức năng để nhận các gói không được cài đặt và sau đó cài đặt chúng. Trong mẫu dưới đây, chúng tôi kiểm tra xem các gói ggplot2Rcppđược cài đặt trước khi cài đặt chúng.

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

Trong một dòng, ở trên có thể được viết là:

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

Tôi sử dụng cách tiếp cận tương tự. Chúng tôi cũng có thể sử dụng installed.packages()[,'Package']thay vì rownames(installed.packages()).
Scudelletti

3

Tôi đã thực hiện chức năng cài đặt và tải các gói R yêu cầu một cách im lặng. Hy vọng có thể giúp đỡ. Đây là mã:

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

3

Phiên bản sắp tới của RStudio (1.2), đã có sẵn dưới dạng bản xem trước, sẽ bao gồm một tính năng để phát hiện các gói library()require()cuộc gọi bị thiếu và nhắc người dùng cài đặt chúng:

Phát hiện các gói R bị thiếu

Nhiều tập lệnh R mở bằng các lệnh gọi library()require()tải các gói chúng cần để thực thi. Nếu bạn mở tập lệnh R tham chiếu các gói mà bạn chưa cài đặt, RStudio sẽ cung cấp để cài đặt tất cả các gói cần thiết chỉ bằng một cú nhấp chuột. Không gõ install.packages()nhiều lần cho đến khi các lỗi biến mất!
https://blog.rstudio.com/2018/11/19/rstudio-1-2-preview-the-little-things/

Điều này dường như giải quyết mối quan tâm ban đầu của OP rất tốt:

Nhiều người trong số họ là người dùng R mới làm quen / trung cấp và không nhận ra rằng họ phải cài đặt các gói họ chưa có.


2

Về mục tiêu chính của bạn "để cài đặt thư viện mà họ chưa có." Và bất kể sử dụng "instllaed.packages ()". Các chức năng sau đây che dấu chức năng ban đầu của yêu cầu. Nó cố gắng tải và kiểm tra gói có tên "x", nếu nó chưa được cài đặt, hãy cài đặt trực tiếp bao gồm cả các phụ thuộc; và cuối cùng tải nó bình thường. bạn đổi tên tên hàm từ 'request' thành 'library' để duy trì tính toàn vẹn. Hạn chế duy nhất là tên gói nên được trích dẫn.

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

Vì vậy, bạn có thể tải và cài đặt gói theo cách cũ của R. yêu cầu ("ggplot2") yêu cầu ("Rcpp")


Nếu bạn không thích câu trả lời của bạn nữa, đừng phá hoại nó - chỉ cần xóa nó.
Michael Petrotta

Vâng, tôi đã cố gắng, nhưng tôi không thể. Tôi nghĩ rằng phần mở rộng NoScript của FF của tôi đang vô hiệu hóa nó hoặc tôi không có quyền và tín dụng để xóa câu trả lời của riêng tôi. LoL Tuy nhiên, tôi nghĩ Livius khá gần với câu trả lời của tôi, suy nghĩ mà không che giấu. Cảm ơn Michael Petrotta. để thông báo.
GeoObserver

Bạn sẽ thấy một deleteliên kết trên những ý kiến ​​này. Nếu bạn không và bạn vẫn muốn xóa, hãy sử dụng flagliên kết, chọn "khác" và giải thích cho người điều hành rằng bạn muốn xóa câu trả lời.
Michael Petrotta

2

Khá cơ bản một.

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

2

Tôi nghĩ tôi sẽ đóng góp cái tôi sử dụng:

testin <- function(package){if (!package %in% installed.packages())    
install.packages(package)}
testin("packagename")


2

Sử dụng phương pháp tiếp cận chức năng ẩn danh và gia đình, bạn có thể:

  1. Cố gắng đính kèm tất cả các gói được liệt kê.
  2. Chỉ cài đặt thiếu (sử dụng ||đánh giá lười biếng).
  3. Cố gắng đính kèm lại những cái bị thiếu ở bước 1 và được cài đặt ở bước 2.
  4. In từng gói trạng thái tải cuối cùng ( 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 

1

Tôi sử dụng cách sau đây để kiểm tra xem gói đã được cài đặt chưa và nếu phụ thuộc được cập nhật, sau đó tải gói.

p<-c('ggplot2','Rcpp')
install_package<-function(pack)
{if(!(pack %in% row.names(installed.packages())))
{
  update.packages(ask=F)
  install.packages(pack,dependencies=T)
}
 require(pack,character.only=TRUE)
}
for(pack in p) {install_package(pack)}

completeFun <- function(data, desiredCols) {
  completeVec <- complete.cases(data[, desiredCols])
  return(data[completeVec, ])
}

1

Đây là mã của tôi cho nó:

packages <- c("dplyr", "gridBase", "gridExtra")
package_loader <- function(x){
    for (i in 1:length(x)){
        if (!identical((x[i], installed.packages()[x[i],1])){
            install.packages(x[i], dep = TRUE)
        } else {
            require(x[i], character.only = TRUE)
        }
    }
}
package_loader(packages)

1
 48 lapply_install_and_load <- function (package1, ...)
 49 {
 50     #
 51     # convert arguments to vector
 52     #
 53     packages <- c(package1, ...)
 54     #
 55     # check if loaded and installed
 56     #
 57     loaded        <- packages %in% (.packages())
 58     names(loaded) <- packages
 59     #
 60     installed        <- packages %in% rownames(installed.packages())
 61     names(installed) <- packages
 62     #
 63     # start loop to determine if each package is installed
 64     #
 65     load_it <- function (p, loaded, installed)
 66     {
 67         if (loaded[p])
 68         {
 69             print(paste(p, "loaded"))
 70         }
 71         else
 72         {
 73             print(paste(p, "not loaded"))
 74             if (installed[p])
 75             {
 76                 print(paste(p, "installed"))
 77                 do.call("library", list(p))
 78             }
 79             else
 80             {
 81                 print(paste(p, "not installed"))
 82                 install.packages(p)
 83                 do.call("library", list(p))
 84             }
 85         }
 86     }
 87     #
 88     lapply(packages, load_it, loaded, installed)
 89 }

1
library <- function(x){
  x = toString(substitute(x))
if(!require(x,character.only=TRUE)){
  install.packages(x)
  base::library(x,character.only=TRUE)
}}

Điều này hoạt động với tên gói không được trích dẫn và khá thanh lịch (xem câu trả lời của GeoObserver)


1

Trong trường hợp của tôi, tôi muốn có một lớp lót mà tôi có thể chạy từ dòng lệnh (thực sự thông qua Makefile). Dưới đây là một ví dụ cài đặt "VGAM" và "Feather" nếu chúng chưa được cài đặt:

R -e 'for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")'

Từ trong R nó sẽ chỉ là:

for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")

Không có gì ở đây ngoài các giải pháp trước đó ngoại trừ:

  • Tôi giữ nó ở một dòng
  • Tôi cứng mã repostham số (để tránh mọi quảng cáo hỏi về gương sử dụng)
  • Tôi không bận tâm để xác định một chức năng sẽ được sử dụng ở nơi khác

Cũng lưu ý quan trọng character.only=TRUE(không có nó, requiresẽ cố gắng tải gói p).


0
  packages_installed <- function(pkg_list){
        pkgs <- unlist(pkg_list)
        req <- unlist(lapply(pkgs, require, character.only = TRUE))
        not_installed <- pkgs[req == FALSE]
        lapply(not_installed, install.packages, 
               repos = "http://cran.r-project.org")# add lib.loc if needed
        lapply(pkgs, library, character.only = TRUE)
}

0

Hãy để tôi chia sẻ một chút điên rồ:

c("ggplot2","ggsci", "hrbrthemes", "gghighlight", "dplyr") %>%  # What will you need to load for this script?
  (function (x) ifelse(t =!(x %in% installed.packages()), 
    install.packages(x[t]),
    lapply(x, require))) 
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.