วิธีที่สวยงามในการตรวจสอบแพ็คเกจที่หายไปและติดตั้งหรือไม่


337

ฉันดูเหมือนจะแบ่งปันรหัสจำนวนมากกับผู้เขียนร่วมสมัยนี้ หลายคนเป็นผู้ใช้มือใหม่และระดับกลางและไม่รู้ตัวว่าต้องติดตั้งแพ็คเกจที่ยังไม่มี

มีวิธีโทรที่หรูหราinstalled.packages()เปรียบเทียบกับวิธีที่ฉันกำลังโหลดและติดตั้งหากไม่มีหรือไม่


1
@krlmlr แล้วคำตอบที่ยอมรับนั้นล้าสมัยและต้องมีการแก้ไขใหม่หรือไม่? การทำงานสำหรับฉัน (สำหรับการทดสอบที่รวดเร็วไม่กี่) R version 3.0.2 (2013-09-25) x86_64-w64-mingw32/x64 (64-bit)ภายใต้
Brian Diggs

1
@BrianDiggs: อย่างน้อยสามแพ็คเกจปรากฏว่ามีปัญหานี้มีเพียงหนึ่งที่อ้างอิงด้านล่าง มีมากยิ่งขึ้น - นั่นคือคำถาม
krlmlr

2
@krlmlr ดูเหมือนว่าจะมีปัญหาไก่และไข่แดกดันเกี่ยวกับการใช้แพคเกจเพื่อให้แน่ใจว่า (อื่น ๆ ) มีแพคเกจที่จำเป็น แต่ก็คุ้มค่าที่จะมีใครสักคนที่รู้เรื่องเขียนคำตอบ
Brian Diggs

2
@BrianDiggs: การเริ่มต้นแพคเกจการตรวจสอบการติดตั้งนี้เป็นสิ่งที่จำเป็น แต่มีขนาดเล็ก เว้นแต่ว่าฟังก์ชั่นการค้นหาจะเข้ามาในbase... ;-) #
24432 krlmlr

คำตอบ:


304

ใช่. หากคุณมีรายการแพ็กเกจเปรียบเทียบกับเอาต์พุตจากinstalled.packages()[,"Package"]และติดตั้งแพ็กเกจที่หายไป บางสิ่งเช่นนี้:

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)

มิฉะนั้น:

หากคุณใส่รหัสของคุณในแพ็คเกจและทำให้การอ้างอิงนั้นจะถูกติดตั้งโดยอัตโนมัติเมื่อคุณติดตั้งแพคเกจของคุณ


11
ฉันคิดว่าไวยากรณ์ที่เหมาะสมคือ: if(length(new.packages)>0) {install.packages(new.packages)}

5
@psql, Shine ถูกต้องเนื่องจาก "> 0" เป็น "implicit" ภายในเงื่อนไข if เรียกใช้สิ่งนี้เพื่อยืนยัน:new.packages <- c(1,2) length(new.packages) if(length(new.packages)){print("hello!")}else{print("oh no!")}
Andrea Cirillo

7
เอกสารของ install.packages ระบุว่า: "อาจช้าเมื่อมีการติดตั้งแพ็คเกจนับพันดังนั้นอย่าใช้สิ่งนี้เพื่อตรวจสอบว่ามีการติดตั้งแพ็คเกจที่ระบุชื่อหรือไม่ (ใช้ system.file หรือ find.package) ... "
Thomas Materna

2
เห็นด้วยกับโทมัสสิ่งนี้จะมีประสิทธิภาพที่ดีกว่าrequireแทนที่จะตรวจสอบinstalled.packages
แมทธิว

1
packratถูกสร้างขึ้นมาเพื่อสิ่งนี้ มันเป็นระบบการจัดการบรรจุภัณฑ์ที่ทำซ้ำได้ วิธีนี้จะไปในทางที่ผิดและยุ่งกับสภาพแวดล้อมของคนอื่นและไม่ทำซ้ำ Packrat มีโฟลเดอร์และสภาพแวดล้อมเป็นของตัวเองสำหรับไลบรารีที่แชร์ rstudio.github.io/packrat
mtelesha

231

Dason K. และฉันมีแพคเกจPacmanที่สามารถทำได้อย่างนี้ ฟังก์ชั่นp_loadในแพ็คเกจทำสิ่งนี้ บรรทัดแรกคือเพียงเพื่อให้แน่ใจว่าติดตั้ง Pacman

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

1
สถานะของแพ็คเกจคืออะไร ฉันไม่เห็นใน C-RAN
ลดราคา

4
@Moseose pacmanได้เข้าร่วม CRAN แล้วcran.r-project.org/web/packages/pacman/index.html
Tyler Rinker

6
ติดตั้งแล้วและใช้งานได้อย่างยอดเยี่ยม ควรเป็นส่วนหนึ่งของฐาน!
AndyF

3
วิธีเดียวที่จะดีกว่านี้ก็คือหากตรวจสอบ/แล้วและหากพบให้ติดตั้ง / โหลดจาก github โดยอัตโนมัติ
airstrike

4
@NealBarsch ถ้าคุณหมายถึงif (!require("pacman")) install.packages("pacman")มีฟังก์ชั่นใน pacman ที่เรียกp_boot()ว่า maks บรรทัดนี้สำหรับคุณโดยอัตโนมัติและคัดลอกไปยังคลิปบอร์ด
Tyler Rinker

72

คุณสามารถใช้ค่าส่งคืนของrequire:

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

ฉันใช้libraryหลังจากการติดตั้งเพราะมันจะมีข้อยกเว้นหากการติดตั้งไม่สำเร็จหรือไม่สามารถโหลดแพ็คเกจด้วยเหตุผลอื่น คุณทำให้สิ่งนี้แข็งแกร่งและนำกลับมาใช้ใหม่ได้:

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

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

requireข้อเสียในการใช้วิธีนี้คือการที่คุณต้องผ่านชื่อแพคเกจในราคาที่คุณไม่ได้ทำเพื่อความจริง


4
คุณสามารถทำให้ชีวิตของคุณง่ายขึ้นมากโดยใช้character.only = TRUEในrequireแต่ฉันคิดว่าไม่มีอะไรแตกต่างจากคำตอบของฉัน
Simon O'Hanlon

มันดูดี แต่ดูเหมือนจะไม่ทำงานอย่างน้อยสำหรับฉัน เมื่อฉันลองใช้เวอร์ชันที่มีประสิทธิภาพฉันได้รับข้อความแสดงข้อผิดพลาดสองข้อความเนื่องจาก R ไม่รู้วิธีจัดการ "return True" และ "return eval" ด้วยเหตุผลบางอย่าง ดังนั้นฉันจึงต้องการฟังก์ชั่นเช่นนี้ที่โหลดแพ็กเกจถ้ามีอยู่ในห้องสมุดของฉันและติดตั้งแพคเกจ (และโหลดภายหลัง) เป็นการดีที่ฉันจะใช้สิ่งนี้เป็นค่าเริ่มต้นในการโหลดแพคเกจ อย่างน้อยก็ดูเหมือนจะเหมาะสมที่จะทำเช่นนั้นและจะช่วยประหยัดเวลา
เฟเบียน

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

"ggplot2" เป็นแพ็คเกจ มันตรวจสอบเพื่อดูว่ามีการติดตั้งแพ็กเกจหรือไม่หากไม่ได้ติดตั้ง จากนั้นโหลดแพ็กเกจโดยไม่คำนึงถึงสาขาที่ใช้


21

โซลูชันนี้จะใช้เวกเตอร์อักขระของชื่อแพ็คเกจและพยายามโหลดหรือติดตั้งหากการโหลดล้มเหลว มันขึ้นอยู่กับพฤติกรรมการกลับมาของrequireการทำเช่นนี้เพราะ ...

require ส่งกลับ (ล่องหน) เป็นตรรกะที่ระบุว่าแพคเกจที่จำเป็นสามารถใช้ได้

ดังนั้นเราสามารถดูได้ว่าเราสามารถโหลดแพ็คเกจที่ต้องการหรือไม่หากติดตั้งด้วยการอ้างอิง ให้เวกเตอร์ตัวละครของแพ็คเกจที่คุณต้องการโหลด ...

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

คุณไม่ต้องการโทรrequireอีกครั้งหลังจากติดตั้งหรือไม่
krlmlr

@krlmlr Nope เพราะเพื่อให้ifคำสั่งได้รับการประเมินมันต้องประเมินก่อนผลrequireข้างเคียงของการโหลดแพคเกจถ้ามันมีอยู่!
Simon O'Hanlon

1
SimonO101: ฉันคิดว่า krlmlr หมายถึงในคำสั่ง if หลังจากการเรียกไปinstall.packagesเนื่องจากจะไม่โหลดแพคเกจนั้นจริง ๆ แต่ (ถึง @krlmlr) ฉันสงสัยว่าเจตนาคือส่วนรหัสนี้จะถูกเรียกเพียงครั้งเดียวเท่านั้น คุณจะไม่เขียนสิ่งนี้ทุกครั้งที่คุณต้องการแพ็คเกจ แต่คุณจะเรียกใช้ก่อนเวลาแล้วโทรrequireตามปกติตามต้องการ
แอรอนออกจาก Stack Overflow

@Aaron ใช่แล้วตกลงฉันเห็นว่าคุณหมายถึงอะไรและใช่การตีความของคุณถูกต้อง ฉันจะแก้ไขเล็กน้อยเพื่อให้ชัดเจนยิ่งขึ้นเกี่ยวกับการโหลดหลังจากการติดตั้ง
Simon O'Hanlon

1
มันจะดีกว่าไหมถ้าrequireใช้การเรียกครั้งที่สองlibraryเพื่อไม่ให้ส่งเสียงดังถ้ามันยังไม่สามารถแนบแพ็คเกจได้ด้วยเหตุผลบางอย่าง?
kabdulla

18

คำตอบมากมายข้างต้น (และซ้ำซ้อนกับคำถามนี้) ขึ้นอยู่กับinstalled.packagesว่ารูปแบบใดที่ไม่ดี จากเอกสาร:

สิ่งนี้อาจช้าเมื่อติดตั้งแพ็คเกจเป็นพันดังนั้นอย่าใช้สิ่งนี้เพื่อตรวจสอบว่ามีการติดตั้งแพ็คเกจที่มีชื่อ (ใช้ system.file หรือ find.package) หรือไม่เพื่อดูว่าแพ็คเกจใช้งานได้หรือไม่ ส่งคืนค่า) หรือค้นหารายละเอียดของแพ็กเกจจำนวนน้อย (ใช้ packageDescription) จำเป็นต้องอ่านไฟล์หลายไฟล์ต่อแพ็คเกจที่ติดตั้งซึ่งจะช้าใน Windows และในบางระบบไฟล์ที่ติดตั้งบนเครือข่าย

ดังนั้นวิธีที่ดีกว่าคือพยายามโหลดแพ็กเกจที่ใช้requireและติดตั้งหากการโหลดล้มเหลว ( requireจะกลับมาFALSEหากไม่พบ) ฉันชอบการนำไปใช้นี้:

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

ซึ่งสามารถใช้ดังนี้:

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

วิธีนี้จะโหลดแพ็กเกจทั้งหมดจากนั้นย้อนกลับและติดตั้งแพ็กเกจที่หายไปทั้งหมด (ซึ่งหากคุณต้องการเป็นสถานที่ที่สะดวกในการแทรกพร้อมต์เพื่อถามว่าผู้ใช้ต้องการติดตั้งแพ็กเกจหรือไม่) แทนที่จะเรียกinstall.packagesแยกต่างหากสำหรับแต่ละแพ็คเกจมันจะส่งเวกเตอร์ทั้งหมดของแพ็คเกจที่ถอนการติดตั้งเพียงครั้งเดียว

นี่คือฟังก์ชั่นเดียวกัน แต่มีหน้าต่างโต้ตอบที่ถามว่าผู้ใช้ต้องการติดตั้งแพ็คเกจที่หายไปหรือไม่

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

นี่เป็นวิธีที่สง่างามและดีกว่าที่ยอมรับ ฉันจะรวมไว้ในห้องสมุดส่วนตัวของฉัน ขอบคุณ
Bing

15

ถึงแม้ว่าคำตอบของเชนเป็นสิ่งที่ดีจริงๆสำหรับหนึ่งในโครงการของฉันฉันต้องการที่จะลบข้อความ ouput คำเตือนและติดตั้งแพคเกจโดยอัตโนมัติ ในที่สุดฉันก็ได้รับสคริปต์นี้:

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

ใช้:

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

นี่คือวัตถุประสงค์ของแพ็กเกจ rbundler : เพื่อให้วิธีการควบคุมแพ็คเกจที่ติดตั้งสำหรับโครงการเฉพาะ ขณะนี้แพคเกจใช้งานได้กับฟังก์ชัน devtools เพื่อติดตั้งแพ็คเกจลงในไดเรกทอรีของโครงการ การทำงานจะคล้ายกับทับทิมBundler

หากโครงการของคุณเป็นแพ็คเกจ (แนะนำ) สิ่งที่คุณต้องทำคือโหลด rbundler และรวมแพ็คเกจ bundleฟังก์ชั่นจะดูที่แพคเกจของDESCRIPTIONไฟล์เพื่อตรวจสอบว่าแพคเกจที่จะกำ

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

ตอนนี้แพ็คเกจจะถูกติดตั้งในไดเรกทอรี. Round

หากโครงการของคุณไม่ใช่แพ็คเกจคุณสามารถปลอมมันได้โดยสร้างDESCRIPTIONไฟล์ในไดเรกทอรีรากของโครงการด้วยฟิลด์ Depends ที่แสดงรายการแพ็คเกจที่คุณต้องการติดตั้ง (พร้อมข้อมูลรุ่นที่เป็นทางเลือก):

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

นี่คือ repo GitHub สำหรับโครงการหากคุณสนใจในการสนับสนุน: rbundler


5

แน่ใจ

คุณต้องเปรียบเทียบ 'แพ็คเกจที่ติดตั้ง' กับ 'แพ็คเกจที่ต้องการ' มันใกล้เคียงกับสิ่งที่ฉันทำกับCRANberries มากเพราะฉันต้องเปรียบเทียบ 'แพ็คเกจที่รู้จักกันที่เก็บไว้' กับ 'แพ็คเกจปัจจุบันที่รู้จักกัน' เพื่อกำหนดแพ็คเกจใหม่และ / หรืออัปเดต

ทำสิ่งที่ชอบ

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

เพื่อรับแพ็กเกจที่รู้จักทั้งหมดโทร Simular สำหรับแพ็กเกจที่ติดตั้งในปัจจุบันและเปรียบเทียบกับแพ็กเกจเป้าหมายที่กำหนด


5

ใช้packratเพื่อให้ไลบรารีที่แบ่งใช้นั้นเหมือนกันทุกประการและไม่เปลี่ยนแปลงสภาพแวดล้อมของผู้อื่น

ในแง่ของความสง่างามและแนวปฏิบัติที่ดีที่สุดฉันคิดว่าคุณกำลังจะไปในทางที่ผิด แพคเกจpackratถูกออกแบบมาสำหรับปัญหาเหล่านี้ พัฒนาโดย RStudio โดย Hadley Wickham แทนที่จะต้องติดตั้งการพึ่งพาและอาจทำให้ระบบสภาพแวดล้อมของใครบางคนล้มเหลวpackratใช้ไดเรกทอรีของตัวเองและติดตั้งการพึ่งพาทั้งหมดสำหรับโปรแกรมของคุณที่นั่นและไม่ได้สัมผัสสภาพแวดล้อมของใครบางคน

Packrat เป็นระบบการจัดการการพึ่งพาสำหรับ R

การพึ่งพาแพ็คเกจ R สามารถทำให้หงุดหงิดได้ คุณเคยลองใช้การทดลองและข้อผิดพลาดหรือไม่ในการค้นหาว่าคุณต้องติดตั้งแพ็กเกจ R ใดเพื่อให้โค้ดของคนอื่นทำงานได้ ? คุณเคยอัปเดตแพคเกจเพื่อรับรหัสในหนึ่งในโปรเจ็กต์ของคุณให้ทำงานเพียงเพื่อจะพบว่าแพ็คเกจที่อัพเดตทำให้โค้ดในโปรเจ็กต์อื่นหยุดทำงานหรือไม่

เราสร้าง packrat เพื่อแก้ไขปัญหาเหล่านี้ ใช้ packrat เพื่อทำให้โครงการ R ของคุณมากขึ้น:

  • ที่แยกได้: การติดตั้งแพคเกจใหม่หรืออัปเดตสำหรับโครงการหนึ่งจะไม่ทำให้โครงการอื่น ๆ ของคุณเสียหายและในทางกลับกัน นั่นเป็นเพราะ packrat ให้แต่ละโครงการเป็นห้องสมุดส่วนตัว
  • แบบพกพา: พกพาโครงการของคุณจากคอมพิวเตอร์เครื่องหนึ่งไปยังอีกเครื่องหนึ่งได้อย่างง่ายดายแม้ในแพลตฟอร์มที่ต่างกัน Packrat ทำให้ง่ายต่อการติดตั้งแพ็คเกจที่โครงการของคุณขึ้นอยู่กับ
  • ทำซ้ำได้: Packrat บันทึกรุ่นแพ็คเกจที่แน่นอนที่คุณต้องใช้และรับรองว่ารุ่นที่แน่นอนนั้นเป็นรุ่นที่ติดตั้งทุกที่ที่คุณไป

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


4

ฟังก์ชั่นง่าย ๆ ดังต่อไปนี้ทำงานเหมือนมีเสน่ห์:

  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

ฉันใช้ฟังก์ชั่นต่อไปนี้เพื่อติดตั้งแพคเกจหากrequire("<package>")ออกจากแพ็คเกจไม่พบข้อผิดพลาด มันจะสอบถามทั้ง - CRAN และที่เก็บ Bioconductor สำหรับแพ็คเกจที่ขาดหายไป

ดัดแปลงมาจากงานต้นฉบับโดย 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)))
  }
}

ตัวอย่าง:

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

PS: update.packages(ask = FALSE)& biocLite(character(), ask=FALSE)จะอัปเดตแพ็คเกจที่ติดตั้งทั้งหมดในระบบ การดำเนินการนี้อาจใช้เวลานานและถือว่าเป็นการอัพเกรด R เต็มรูปแบบซึ่งอาจไม่ได้รับการรับประกันตลอดเวลา!


มันสามารถปรับปรุงได้โดยการตรวจสอบว่าแพ็คเกจมีให้ใช้งานบน cran หรือ bc หรือไม่ นอกจากนี้ควรใช้ไลบรารีในตอนท้ายเพื่อทิ้งข้อผิดพลาดหากการติดตั้งล้มเหลวหรือไม่มีแพ็คเกจ ดูรุ่นปรับปรุงของฉันเรียกว่าloadpack()ในraw.githubusercontent.com/holgerbrandl/datautils/master/R/...
โฮล Brandl

4

คุณสามารถใช้setdiffฟังก์ชั่นเพื่อรับแพ็คเกจที่ไม่ได้ติดตั้งแล้วติดตั้งได้ ในตัวอย่างด้านล่างเราตรวจสอบว่ามีการติดตั้งggplot2และRcppแพคเกจก่อนติดตั้งหรือไม่

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

ในหนึ่งบรรทัดข้างต้นสามารถเขียนเป็น:

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

ฉันใช้วิธีการเดียวกัน นอกจากนี้เรายังสามารถใช้แทนinstalled.packages()[,'Package'] rownames(installed.packages())
Scudelletti

3

ฉันได้ติดตั้งฟังก์ชั่นเพื่อติดตั้งและโหลดแพ็กเกจ 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);

3

เวอร์ชั่นใหม่ของ 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/

ดูเหมือนว่าจะแก้ไขข้อกังวลเดิมของ OP ได้เป็นอย่างดี:

หลายคนเป็นผู้ใช้มือใหม่และระดับกลางและไม่รู้ตัวว่าต้องติดตั้งแพ็คเกจที่ยังไม่มี


2

เกี่ยวกับวัตถุประสงค์หลักของคุณ "เพื่อติดตั้งไลบรารีพวกเขายังไม่มี" และไม่คำนึงถึงการใช้ "instllaed.packages ()" ฟังก์ชั่นต่อไปนี้ปกปิดฟังก์ชั่นดั้งเดิมของความต้องการ มันพยายามที่จะโหลดและตรวจสอบแพคเกจชื่อ "x" ถ้ามันไม่ได้ติดตั้งติดตั้งโดยตรงรวมถึงการพึ่งพา; และสุดท้ายโหลดมัน normaly คุณเปลี่ยนชื่อฟังก์ชั่นจาก 'ต้องการ' เป็น 'ห้องสมุด' เพื่อรักษาความสมบูรณ์ ข้อ จำกัด เพียงอย่างเดียวคือชื่อแพคเกจควรจะยกมา

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

ดังนั้นคุณสามารถโหลดและติดตั้งแพ็กเกจแบบเก่าของอาร์อาร์ต้องการ ("ggplot2") ต้องการ ("Rcpp")


หากคุณไม่ชอบคำตอบของคุณอีกต่อไปอย่าทำลายมัน - เพียงแค่ลบทิ้ง
Michael Petrotta

ฉันลองแล้ว แต่ก็ทำไม่ได้ ฉันคิดว่าส่วนขยาย NoScript ของ FF ของฉันปิดใช้งานอยู่หรือฉันไม่มีสิทธิ์และเครดิตในการลบคำตอบของฉันเอง ฮ่า ๆ อย่างไรก็ตามฉันคิดว่า Livius ค่อนข้างใกล้กับคำตอบของฉันคิดโดยไม่ปิดบัง ขอบคุณ Michael Petrotta สำหรับการแจ้งเตือน
GeoObserver

คุณควรเห็นdeleteลิงค์ด้านบนความคิดเห็นเหล่านี้ หากคุณไม่ต้องการและยังคงต้องการลบให้ใช้flagลิงก์เลือก "อื่น ๆ " และอธิบายถึงผู้ดำเนินรายการที่คุณต้องการลบคำตอบ
Michael Petrotta

2

พื้นฐานค่อนข้างหนึ่ง

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

2

คิดว่าฉันจะสนับสนุนสิ่งที่ฉันใช้:

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


2

การใช้ตระกูล 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 

1

ฉันใช้สิ่งต่อไปนี้ซึ่งจะตรวจสอบว่ามีการติดตั้งแพคเกจหรือไม่และมีการปรับปรุงการอ้างอิงหรือไม่จากนั้นโหลดแพ็คเกจ

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

นี่คือรหัสของฉัน:

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

ใช้งานได้กับชื่อแพ็คเกจที่ไม่ได้กล่าวถึงและมีความสวยงามพอสมควร (คำตอบของ GeoObserver)


1

ในกรณีของฉันฉันต้องการซับหนึ่งที่ฉันสามารถเรียกใช้จาก commandline (จริง ๆ แล้วผ่าน Makefile) นี่คือตัวอย่างการติดตั้ง "VGAM" และ "feather" หากยังไม่ได้ติดตั้ง:

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

จากภายใน R มันก็จะเป็น:

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

ไม่มีอะไรนอกเหนือจากโซลูชันก่อนหน้ายกเว้นที่:

  • ฉันเก็บไว้เป็นบรรทัดเดียว
  • ฉันเขียนโค้ดreposพารามิเตอร์ยาก(เพื่อหลีกเลี่ยงป๊อปอัปที่ถามเกี่ยวกับมิเรอร์เพื่อใช้)
  • ฉันไม่สนใจที่จะกำหนดฟังก์ชั่นที่จะใช้ที่อื่น

ยังทราบความสำคัญcharacter.only=TRUE(โดยไม่ได้มันrequireจะพยายามโหลดแพคเกจ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

ให้ฉันแบ่งปันความบ้าสักหน่อย:

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))) 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.