3

我之前问过这个问题,但仍然无法让它工作。我正在尝试在启动 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)时,我认为贾斯汀建议使用 if 语句检查包可以解决问题。但这似乎只解决了我从 CRAN 安装的包的问题,​​而不是自定义包。

对此事的任何帮助将不胜感激!

4

3 回答 3

4

我不明白你为什么要这样做。只要让他们指向.libPaths同一个地方。即,而不是install.packages(...),只需在 Rprofile.site 中添加一行,上面写着

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

您可能可以做的另一件事是system拨打电话。我对在 Windows 下安装软件包知之甚少,但在 Unix-alike 上,install.packages你可以做这样的事情,而不是使用:

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

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

编辑

在咨询了这个 SO answer之后,看起来你可以在 Windows 上做这样的事情(假设你已经安装了Rtools),虽然我没有测试过。

system("Rcmd --vanilla INSTALL customPackage")
于 2012-07-17T21:23:17.503 回答
2

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

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

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

    如果您希望 '~/.Renviron' 或 '~/.Rprofile' 被子 R 进程(例如由 R CMD check 和 R CMD build 运行的那些)忽略,请将适当的环境变量 R_ENVIRON_USER 或 R_PROFILE_USER 设置为(如果可能,它不在 Windows 上)“”或不存在的文件的名称。

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

    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.

于 2019-04-05T16:14:47.503 回答
0

您可以使用以下功能安装软件包而无需重新加载.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())
}
于 2016-12-19T18:28:18.090 回答