Programing

누락 된 패키지를 확인하고 설치하는 우아한 방법?

lottogame 2020. 3. 15. 09:32
반응형

누락 된 패키지를 확인하고 설치하는 우아한 방법?


요즘에는 공동 저자와 많은 코드를 공유하고있는 것 같습니다. 이들 중 다수는 초보자 / 중급 R 사용자이며 아직 가지고 있지 않은 패키지를 설치해야한다는 것을 인식하지 못합니다.

전화하는 우아한 방법이 installed.packages()있습니까, 누락 된 경우로드하고 설치하는 것과 비교할 수 있습니까?


예. 패키지 목록이 있으면 출력 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)

그렇지 않으면:

코드를 패키지에 넣고 의존성을 만들면 패키지를 설치할 때 자동으로 설치됩니다.


Dason K.와 저는 이것을 잘 할 수 있는 팩맨 패키지를 가지고 있습니다. p_load패키지 의 기능 이이를 수행합니다. 첫 번째 줄은 pacman이 설치되었는지 확인하는 것입니다.

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

반환 값은 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입니다. 실제로는하지 않습니다 .


이 솔루션은 패키지 이름의 문자형 벡터를 가져 와서로드하거나로드에 실패하면 설치합니다. 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" ) )

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

"ggplot2"는 패키지입니다. 패키지가 설치되어 있지 않은지 확인합니다. 그런 다음 어떤 브랜치에 관계없이 패키지를로드합니다.


Shane의 대답은 정말 좋지만 내 프로젝트 중 하나에 대해 출력 메시지, 경고를 제거하고 패키지를 자동으로 설치해야했습니다 . 마침내이 스크립트를 얻었습니다.

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

위의 많은 답변 (그리고이 질문의 사본에 대한)은 installed.packages어느 형식이 나쁜지 에 의존 합니다. 설명서에서 :

수천 개의 패키지가 설치 될 때 속도가 느릴 수 있으므로이 패키지를 사용하여 명명 된 패키지가 설치되어 있는지 (system.file 또는 find.package 사용) 확인하거나 패키지를 사용할 수 있는지 확인하십시오 (전화 요청 및 반환 값) 또는 적은 수의 패키지에 대한 세부 정보 찾기 (packageDescription 사용) 설치된 패키지 당 여러 파일을 읽어야합니다. Windows 및 일부 네트워크 마운트 파일 시스템에서는 속도가 느립니다.

따라서 더 나은 방법은 requireand를 사용하여 패키지를로드하고 로드에 실패하면 설치하는 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각 패키지에 대해 별도로 호출하는 대신 제거 된 패키지의 전체 벡터를 한 번만 전달합니다.

동일한 기능이지만 사용자가 누락 된 패키지를 설치할 것인지 묻는 Windows 대화 상자가 있습니다.

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

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

이것은 rbundler 패키지 의 목적입니다 . 특정 프로젝트에 설치된 패키지를 제어하는 ​​방법을 제공하는 것입니다. 현재 패키지는 devtools 기능과 함께 작동하여 패키지를 프로젝트 디렉토리에 설치합니다. 이 기능은 Ruby의 bundler 과 유사합니다 .

프로젝트가 패키지 (권장) 인 경우 리 번 들러를로드하고 패키지를 번들하기 만하면됩니다. bundle함수는 패키지 DESCRIPTION파일을 보고 번들로 묶을 패키지를 결정합니다.

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

이제 패키지는 .Rbundle 디렉토리에 설치됩니다.

프로젝트가 패키지가 아닌 경우, DESCRIPTION설치하려는 패키지를 나열하는 Depends 필드 (옵션 버전 정보 포함)를 사용하여 프로젝트의 루트 디렉토리에 파일 을 작성하여 위조 할 수 있습니다 .

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

rbundler에 관심이 있다면 프로젝트에 대한 github 저장소가 있습니다 .


확실한.

'설치된 패키지'와 '원하는 패키지'를 비교해야합니다. '저장된 알려진 패키지'와 '현재 알려진 패키지'를 비교하여 새 패키지 및 / 또는 업데이트 된 패키지를 결정해야하므로 CRANberries수행하는 작업과 매우 비슷 합니다.

그래서 같은 일을

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

알려진 모든 패키지를 가져 오려면 현재 설치된 패키지를 동시에 호출하고 지정된 대상 패키지 세트와 비교하십시오.


다음과 같은 간단한 기능이 매력처럼 작동합니다.

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

(내 것이 아니라 웹에서이를 발견하고 그 이후로 사용 해 왔습니다. 원본 출처를 모름)


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 업그레이드로 간주하십시오!


setdiff기능을 사용하여 설치되지 않은 패키지를 가져온 다음 설치할 수 있습니다. 아래 샘플에서는 패키지를 설치하기 전에 ggplot2Rcpp패키지가 설치되어 있는지 확인 합니다.

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

한 줄에 위와 같이 쓸 수 있습니다 :

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

packrat공유 라이브러리가 정확히 동일하고 다른 환경을 변경하지 않도록 사용하십시오 .

우아함과 모범 사례 측면에서 근본적으로 잘못된 방향으로 가고 있다고 생각합니다. 패키지 packrat는 이러한 문제를 위해 설계되었습니다. 그것은 Hadley Wickham에 의해 RStudio에 의해 개발되었습니다. 대신 의존성을 설치하고 누군가를 엉망으로 만들 수있는 환경 시스템 packrat은 자체 디렉토리를 사용하고 프로그램에 대한 모든 의존성을 설치하고 누군가의 환경을 건드리지 않습니다.

Packrat는 R의 종속성 관리 시스템입니다.

R 패키지 종속성은 실망 스러울 수 있습니다. 다른 사람의 코드를 작동시키기 위해 어떤 R 패키지를 설치해야하는지 파악하기 위해 시행 착오를 겪은 적이 있습니까? ? 프로젝트 중 하나의 코드가 작동하도록 패키지를 업데이트 한 적이 있습니까? 업데이트 된 패키지로 인해 다른 프로젝트의 코드가 작동을 멈추는 것만 찾으셨습니까?

이러한 문제를 해결하기 위해 packrat을 구축했습니다. packrat를 사용하여 R 프로젝트를 더 많이 만드십시오.

  • 격리 됨 : 한 프로젝트에 새 패키지 나 업데이트 된 패키지를 설치해도 다른 프로젝트가 중단되지 않으며 그 반대도 마찬가지입니다. packrat가 각 프로젝트에 자체 개인 패키지 라이브러리를 제공하기 때문입니다.
  • 이식성 : 한 플랫폼에서 다른 플랫폼으로 프로젝트를 쉽게 전송할 수 있습니다. Packrat를 사용하면 프로젝트가 의존하는 패키지를 쉽게 설치할 수 있습니다.
  • 재현성 : Packrat은 사용자가 사용하는 정확한 패키지 버전을 기록하고 정확한 버전이 어디에서나 설치되도록합니다.

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


필요한 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);

"아직 가지고 있지 않은 라이브러리를 설치하는 주요 목표"와 "instllaed.packages ()"사용 여부에 관계없이. 다음 함수는 필요한 원래 기능을 숨 깁니다. 이름이 지정된 패키지 "x"를로드하고 확인하려고 시도합니다 (설치되어 있지 않은 경우 종속성을 포함하여 직접 설치). 마지막으로 정상적으로로드하십시오. 무결성을 유지하기 위해 함수 이름을 'require'에서 'library'로 이름을 바꿉니다. 패키지 이름을 인용해야합니다.

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

따라서 R의 구식 방식 인 패키지를로드하고 설치할 수 있습니다. require ( "ggplot2") require ( "Rcpp")


아주 기본적인 것입니다.

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

내가 사용하는 것을 공헌하겠다고 생각했습니다.

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

랩 패밀리 및 익명 함수 접근 방식을 사용하면 다음을 수행 할 수 있습니다.

  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 
    

이미 미리보기로 제공되는 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의 원래 관심사를 특히 잘 다루는 것 같습니다.

이들 중 다수는 초보자 / 중급 R 사용자이며 아직 가지고 있지 않은 패키지를 설치해야한다는 것을 인식하지 못합니다.


다음을 사용하여 패키지가 설치되어 있고 종속성이 업데이트되었는지 확인한 다음 패키지를로드합니다.

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

여기 내 코드가 있습니다 :

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)

 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 }

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

이것은 인용되지 않은 패키지 이름으로 작동하며 상당히 우아합니다 (GeoObserver의 답변 참조)


source("https://bioconductor.org/biocLite.R")
if (!require("ggsci")) biocLite("ggsci")

필자의 경우 명령 줄에서 실제로 실행할 수있는 하나의 라이너를 원했습니다 (실제로 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).

참고 URL : https://stackoverflow.com/questions/4090169/elegant-way-to-check-for-missing-packages-and-install-them

반응형