可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I asked this question earlier, but am still unable to get it working. I am trying to install custom packages upon starting R. A lot of the code that is written by us right now is available for editing to the users. To try and protect the code, I am packaging the production level code and having the users install it on their machine during start up.
However, when I try to install packages in RProfile.site file, the program goes into a loop and R is constantly launched over and over. I noticed that a lock file for the package is created along with the package in the library folder within R.
Here is the code I have added to the site file:
if(length(grep("customPackage", installed.packages()[,1]))==0) {
install.packages("customPackage", repos=NULL, type="source")
}
When I try to run this code after starting R (without changing the site file), it installs the package perfectly fine and moves on. However, when I try to do it through the RProfile file, that's when it creates the problems.
Last time I tried resolving this issue (https://stackoverflow.com/questions/10610067/installing-packages-upon-starting-r-session), I thought Justin's suggestion of using the if statement check for packages would fix the problem. But this only seems to solve the problem for packages I install from CRAN and not custom packages.
Any help on this matter would be greatly appreciated!
回答1:
I don't understand why you'd want to do this. Just have them point their .libPaths
to the same place. i.e. instead of install.packages(...)
, just add a line in Rprofile.site that says
.libPaths('/path/to/common/libraries')
require("commonPackage")
Another thing that you might be able to do is make a system
call. I don't know much about installing packages under Windows, but on Unix-alike, instead of using install.packages
you could do something like this:
system("R --vanilla CMD INSTALL customPackage")
Among other things, the --vanilla
flag causes R to be started without using the Rprofile.site file (Your problem is that the Rprofile.site file is being read when R starts, but the Rprofile.site file tells R to install a package which requires starting R, which in turns reads your Rprofile.site file... etc.). Presumably, R --no-site-file INSTALL customPackage
would also work.
Edit
After consulting this SO answer, it looks like you could do something like this on Windows (assuming you have installed Rtools), although I haven't tested it.
system("Rcmd --vanilla INSTALL customPackage")
回答2:
You can use the function below to install package(s) without reloading .Rprofile
:
surround <- function(x, with) {
paste0(with, x, with)
}
peq <- function(x, y) paste(x, y, sep = " = ")
install.packages.vanilla <- function(pkgs, ...){
arguments <- as.list(match.call())[-1]
if(!"repos" %in% names(arguments)){
arguments$repos <- getOption("repos")
}
names_args <- names(arguments)
installArgs <- purrr::map_chr(seq_along(arguments),
function(i){
value <- arguments[[i]]
peq(names_args[i], ifelse(length(value)<2, deparse(value), as.character(list(value))))
})
installArgs <- stringr::str_replace_all(installArgs, "\"", "'")
installCmd <- paste0("utils::install.packages(",
paste(installArgs, collapse = ", "),
")")
fullCmd <- paste(
surround(file.path(R.home("bin"), "R"), with = "\""),
"--vanilla",
"--slave",
"-e",
surround(installCmd, with = "\"")
)
system(fullCmd)
return(invisible())
}
回答3:
As GSee said, the problem is that install.packages
runs R CMD INSTALL
, which starts a new R process that reads the Rprofile.site file, resulting in a loop. To prevent that, Initialization at Start of an R Session says:
If you want ‘~/.Renviron’ or ‘~/.Rprofile’ to be ignored by child R processes (such as those run by R CMD check and R CMD build), set the appropriate environment variable R_ENVIRON_USER or R_PROFILE_USER to (if possible, which it is not on Windows) "" or to the name of a non-existent file.
Adapting that for Rprofile.site, you can set R_PROFILE
to an empty or nonexistent file, before you call install.packages
. For example:
if(length(grep("customPackage", installed.packages()[,1]))==0) {
Sys.setenv(R_PROFILE = "/dev/null")
install.packages("customPackage", repos=NULL, type="source")
Sys.unsetenv("R_PROFILE")
}
Then when R restarts to install packages, it reads an empty Rprofile.site file, so the evil loop is broken.
If the call to install.packages
is in .Rprofile, you can set R_PROFILE_USER
in the same way.