r-从RProfile.site文件安装程序包



我之前问过这个问题,但仍然无法解决。我正在尝试在启动R时安装自定义软件包。我们现在编写的许多代码都可供用户编辑。为了保护代码,我正在打包生产级别的代码,并让用户在启动时将其安装在机器上。

然而,当我尝试在RProfile.site文件中安装软件包时,程序会进入一个循环,R会不断地启动。我注意到,在R.中的库文件夹中,为包创建了一个锁定文件

这是我添加到站点文件的代码:

if(length(grep("customPackage", installed.packages()[,1]))==0) { 
        install.packages("customPackage", repos=NULL, type="source") 
} 

当我尝试在启动R(不更改站点文件)后运行此代码时,它会很好地安装软件包并继续运行。然而,当我尝试通过RProfile文件执行此操作时,它就会产生问题。

上次我尝试解决此问题时(https://stackoverflow.com/questions/10610067/installing-packages-upon-starting-r-session),我认为Justin建议对包使用if语句检查可以解决问题。但这似乎只解决了我从CRAN安装的软件包的问题,而不是自定义软件包。

如果能在这件事上提供任何帮助,我们将不胜感激!

我不明白你为什么要这么做。让他们把.libPaths指向同一个地方。即不使用install.packages(...),只需在Rprofile.site中添加一行即可

.libPaths('/path/to/common/libraries')
require("commonPackage")

您可以做的另一件事是拨打system电话。我不太了解在Windows下安装软件包,但在Unix上,你可以做这样的事情,而不是使用install.packages

system("R --vanilla CMD INSTALL customPackage")

除其他外,--vanilla标志会导致R在不使用Rprofile.site文件的情况下启动(您的问题是R启动时正在读取Rprofile.sete文件,但Rprofile-site文件告诉R安装一个需要启动R的程序包,该程序包会依次读取您的Rprofile/site文件…等等)。据推测,R --no-site-file INSTALL customPackage也会起作用。

编辑

在查阅了这个SO答案后,看起来你可以在Windows上做这样的事情(假设你已经安装了Rtools),尽管我还没有测试过。

system("Rcmd --vanilla INSTALL customPackage")

正如GSee所说,问题是install.packages运行R CMD INSTALL,它启动了一个新的R进程,读取Rprofile.site文件,从而导致循环。打破恶性循环的两种方法:

  1. 检查R是否以交互方式运行:

    if (interactive() && 
        length(grep("customPackage", installed.packages()[,1]))==0) { 
      install.packages("customPackage", repos=NULL, type="source") 
    }
    

    R CMD运行时,interactive()为FALSE,因此这会中断循环。

  2. R_PROFILE环境变量设置为空值或无效值,这样R CMD中的R会话就不会运行您的会话。R会话开始时的初始化说明:

    如果希望子R进程(例如由R CMD检查和R CMD构建运行的进程)忽略"~/.Renviron"或"~/.Rprofile",请将相应的环境变量R_ENVIRON_USER或R_PROFILE_USER设置为(如果可能,它不在Windows上)"或不存在的文件名。

    将其适用于Rprofile.site,您可以在调用install.packages之前将R_PROFILE设置为一个空的或不存在的文件。例如:

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

    然后,当R重新启动以安装软件包时,它会读取一个空的Rprofile.site文件,因此您再次打破循环。

    如果对install.packages的调用在.Rprofile中,则可以用相同的方式设置R_PROFILE_USER

第一种方法更简单,不需要担心可能会覆盖R_PROFILE的现有值。

您可以使用下面的函数安装程序包,而无需重新加载.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())
}

最新更新