私は最近、共著者と多くのコードを共有しているようです。それらの多くは初心者/中級の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.と私にはpacmanパッケージがあり、これをうまく行うことができます。パッケージ内の関数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" ) )
Shaneの答えは本当に良いのですが、私のプロジェクトの1つでは、出力メッセージ、警告を削除し、パッケージをインストールする必要がありましたautomagically。私はついにこのスクリプトを手に入れることができました。
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)
}
}
if (!require('ggplot2')) install.packages('ggplot2'); library('ggplot2')
「ggplot2」はパッケージです。パッケージがインストールされているかどうかを確認し、インストールされていない場合はインストールします。次に、どのブランチを使用したかに関係なく、パッケージをロードします。
上記の回答(およびこの質問の重複)の多くは、悪い形式であるinstalled.packages
に依存しています。ドキュメントから:
何千ものパッケージがインストールされている場合、これは遅くなる可能性があるため、名前付きパッケージがインストールされているかどうかを確認したり(system.fileまたはfind.packageを使用)、パッケージが使用可能かどうかを確認したり(requireを呼び出して戻り値)または少数のパッケージの詳細を検索することもできません(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)
}
}
}
# 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 package :の目的であり、特定のプロジェクト用にインストールされるパッケージを制御する方法を提供します。現在、パッケージはdevtools機能と連携して、プロジェクトのディレクトリにパッケージをインストールします。機能は、Rubyの bundler に似ています。
プロジェクトがパッケージの場合(推奨)、rbundlerをロードしてパッケージをバンドルするだけです。 bundle
関数は、パッケージのDESCRIPTION
ファイルを見て、バンドルするパッケージを決定します。
library(rbundler)
bundle('.', repos="http://cran.us.r-project.org")
これで、パッケージが.Rbundleディレクトリにインストールされます。
プロジェクトがパッケージではない場合、インストールするパッケージをリストするDependsフィールド(オプションのバージョン情報付き)を使用してプロジェクトのルートディレクトリにDESCRIPTION
ファイルを作成することで、それを偽造できます。
Depends: ggplot2 (>= 0.9.2), arm, glmnet
貢献に興味がある場合のプロジェクトのgithubリポジトリは次のとおりです。 rbundler 。
はい。
「インストール済みパッケージ」と「希望するパッケージ」を比較する必要があります。これは、 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)
}
(私のものではなく、しばらく前にウェブ上でこれを見つけて、それ以来それを使用していた。元のソースがわからない)
Packrat
を使用して、共有ライブラリがまったく同じであり、他の環境を変更しないようにします。
優雅さとベストプラクティスの観点から、私はあなたが根本的に間違ったやり方で進んでいると思います。パッケージPackrat
はこれらの問題のために設計されました。これは、Hadley WickhamによるRStudioによって開発されました。依存関係をインストールし、おそらく誰かの環境を台無しにする代わりに、Packrat
は独自のディレクトリを使用して、プログラムにすべての依存関係をインストールし、誰かの環境に影響を与えません。
Packratは、Rの依存関係管理システムです。
Rパッケージの依存関係はイライラする可能性があります。他の人のコードを機能させるためにインストールする必要があるRパッケージを把握するために試行錯誤を使用する必要があり、それらのパッケージが永久にグローバルにインストールされたままになったことがあります。 ?更新されたパッケージが別のプロジェクトのコードの動作を停止させることを見つけるためだけに、パッケージを更新して、プロジェクトの1つでコードを機能させることがありますか?
これらの問題を解決するために、Packratを構築しました。 Packratを使用して、Rプロジェクトをさらに作成します。
- 分離:1つのプロジェクトに新しいパッケージまたは更新されたパッケージをインストールしても、他のプロジェクトが中断されることはありません。これは、Packratが各プロジェクトに独自のプライベートパッケージライブラリを提供するためです。
- ポータブル:異なるプラットフォーム間でも、あるコンピューターから別のコンピューターにプロジェクトを簡単に転送できます。 Packratを使用すると、プロジェクトが依存するパッケージを簡単にインストールできます。
- 再現性:Packratは依存するパッケージの正確なバージョンを記録し、それらの正確なバージョンがどこにでもインストールされることを保証します。
setdiff
関数を使用して、インストールされていないパッケージを取得し、インストールするだけです。以下のサンプルでは、インストールする前にggplot2
およびRcpp
パッケージがインストールされているかどうかを確認します。
unavailable <- setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages()))
install.packages(unavailable)
1行で、上記は次のように記述できます。
install.packages(setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages())))
require("<package>")
がpackage not foundエラーで終了する場合、次の関数を使用してパッケージをインストールします。不足しているパッケージの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アップグレードと見なすことができますが、これは常に保証されるわけではありません!
必要な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()」の使用に関係なく。次の関数は、requireの元の関数をマスクします。指定されたパッケージ「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")
Lapplyファミリと匿名関数アプローチを使用すると、次のことができます。
||
遅延評価を使用)。各パッケージの最終ロードステータス(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
非常に基本的なもの。
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")
パッケージがインストールされているかどうか、依存関係が更新されているかどうかをチェックし、パッケージをロードする以下を使用します。
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, ])
}
プレビューとしてすでに利用可能な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ユーザーであり、まだ持っていないパッケージをインストールする必要があることを認識していません。
私のコードは次のとおりです。
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)
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")
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 }
私の場合、コマンドラインから(実際にはMakefileを介して)実行できる1つのライナーが必要でした。 「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
をロードしようとします)。