最近我似乎和合作者分享了很多代码。他们中的许多人是新手/中级R用户,并没有意识到他们必须安装他们还没有的包。
是否有一种优雅的方式来调用installed.packages(),比较那些我正在加载和安装如果丢失?
最近我似乎和合作者分享了很多代码。他们中的许多人是新手/中级R用户,并没有意识到他们必须安装他们还没有的包。
是否有一种优雅的方式来调用installed.packages(),比较那些我正在加载和安装如果丢失?
当前回答
你可以使用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("<包>")退出包未发现错误。它将查询- CRAN和Bioconductor存储库,以查找丢失的包。
改编自约书亚·威利的原著, 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
注:更新。packages(ask =FALSE) & biocLite(character(), ask=FALSE)将更新系统上所有已安装的软件包。这可能需要很长时间,并将其视为一个完整的R升级,这可能并不总是有保障的!
# 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)
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)运行的一行程序。下面是一个安装“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")
除了前面的解之外,这里没有别的解:
我只说一句 我硬编码回购参数(以避免任何弹出窗口询问使用的镜像) 我不想费心定义一个在其他地方使用的函数
还要注意重要的字符。only=TRUE(如果没有它,require将尝试加载包p)。
确定。
您需要比较“已安装的包”和“所需的包”。这非常接近于我用蔓越莓做的事情,因为我需要比较“存储的已知包”和“当前已知的包”,以确定新的和/或更新的包。
就像这样
AP <- available.packages(contrib.url(repos[i,"url"])) # available t repos[i]
为了获得所有已知的包,模拟调用当前安装的包,并将其与给定的目标包集进行比较。