R脚本:没有叫做...的包?

35

我希望使用Rscript批处理模式运行R文件,但似乎没有加载我需要的库。我遇到的具体错误是:

Error in library(timeSeries) : there is no package called 'timeSeries'
Execution halted

然而我确实有安装timeSeries包,并且可以在Rstudio、RGui和命令行中轻松加载它,问题似乎只出现在使用Rscript运行脚本时。

我的系统/环境变量配置如下:

C:\Program Files\R\R-3.1.0\bin\x64 (Appended to PATH)
R_HOME = C:\Program Files\R\R-3.1.0
R_User = Patrick

我在RStudio、RGui和命令行中运行了相同版本的R。我还从这三个来源检查了.Library并且得到了相同的输出。

如何在命令行中使用我正在使用(已安装)的包来运行Rscript?

编辑:

我正在使用Rscript script.r通过Windows命令行在script.r所在的目录下运行Rscript。

Rscript -e print(.Library)的输出为[1] "C:/PROGRA~1/R/R-31~1.0/library"

这与我提到的其他三个选项一致:[1] "C:/PROGRA~1/R/R-31~1.0/library"

然而,如果我将这个放入我的脚本中:

print(.libPaths()) 
library(timeSeries) #This is the package that failed to load

我得到了一个输出:

[1] "C:/Program Files/R/R-3.1.0/library"
Error in library(timeSeries) : there is no package called 'timeSeries'
Execution halted

在RStudio中对应的调用会额外给出包实际安装位置的路径:

> print(.libPaths())
[1] "C:/Users/Patrick/Documents/R/win-library/3.1" "C:/Program Files/R/R-3.1.0/library"    

  

@flodel - 如您所请求 - pbreach
2
好的...现在用.libPaths()重新开始...你也可以在script.r中的library(timeSeries)之前加入print(.libPaths()) - flodel
好的,太棒了!现在我们知道问题所在了。Rscript库路径没有连接到实际安装包的位置(请参见编辑),但是RStudio和其他软件已经连接上了。 - pbreach
4
您可以通过在调用library(timeSeries)之前添加.libPaths(c("C:/Users/Patrick/Documents/R/win-library/3.1", .libPaths()))来快速解决问题。我不确定为什么.libPaths()最初不同。如果您能够查看?.libPaths的信息以找到原因和更持久的解决方案,那将很好。 - flodel
是的,它可以工作!您想将其发布为答案吗?根据文档,永久解决方案是设置环境变量R_LIBS中的路径。我不确定为什么路径与RScript不同而其他路径却不同。也许这是为了减少启动时间,因为与RScript相比,RScript通常在启动时不会加载太多东西。 - pbreach
显示剩余3条评论
5个回答

11

简而言之,在 R.exe 中调用 Sys.getenv('R_LIBS_USER') 返回的值需要与在命令行中调用此命令返回的值相同:

Rscript.exe -e "Sys.getenv('R_LIBS_USER')"

并且以上数值需要被包含在这个命令行调用中:

Rscript.exe -e ".libPaths()"

请注意,如果更改了R_USER的值(无论是在.Rprofile中还是在用户快捷方式的目标字段中指向R.exe),则R_LIBS_USER的值在 R.exeRscript.exe之间可能会不同。通常情况下,我发现在 Rscript.exe 中未设置用户库(即.libPaths()[2])。

由于我喜欢将R_USER设置为我的USERPROFILE,因此我将以下块包含在我希望在多台计算机上运行或在Rscript.exe.Rprofile中运行的.R文件的顶部(即Rscript -e" path.expand('~/.Rprofile')"):

# =====================================================================
# For compatibility with Rscript.exe: 
# =====================================================================
if(length(.libPaths()) == 1){
    # We're in Rscript.exe
    possible_lib_paths <- file.path(Sys.getenv(c('USERPROFILE','R_USER')),
                                    "R","win-library",
                                    paste(R.version$major,
                                             substr(R.version$minor,1,1),
                                             sep='.'))
    indx <- which(file.exists(possible_lib_paths))
    if(length(indx)){
       .libPaths(possible_lib_paths[indx[1]])
    }
    # CLEAN UP
    rm(indx,possible_lib_paths)
}
# =====================================================================

7

如评论中所提到的,似乎Rscript不能自动识别库路径默认值。我正在编写一个需要从命令行上不同人的计算机中源代码的R脚本,因此我想出了这个更通用的解决方法:

  • First store the default library path in a variable (Rscript-sourced functions can find this, they just don't automatiocally)
  • Then include that path in the library() call with lib.loc = argument.
  • This should work regardless of what the path is on a given computer.

    library.path <- .libPaths()
    library("timeseries", lib.loc = library.path)
    

再次感谢@flodel的指引,让我找到正确的方向。


需要记住一个特殊情况,上述方法可能无法奏效:https://dev59.com/4Ifca4cB1Zd3GeqPj4XI - Paul

4
这个回答对原问题提出者(pbreach)没有帮助,但可能会帮助到其他遇到类似问题的人。我有许多bash .sh脚本文件,它们调用RScript来执行.R文件。我的操作系统是Windows 10,我使用cygwin来执行这些bash文件。一切都运行良好,直到昨天,当我最终将R从Revolution R 8.0.1 beta升级到Microsoft R Open 3.4.1时,每个调用RScript的bash脚本因与此处询问的完全相同的原因而失败(例如Error in library(zoo) : there is no package called 'zoo')。调查发现,如果从DOS shell而不是cygwin bash shell中调用RScript,则RScript实际上可以正常工作。例如,如果我在DOS shell中执行以下操作:
C:\Progra~1\Microsoft\ROpen~1\R-3.4.1\bin\x64\Rscript.exe -e ".libPaths()"

我看到了输出。
[1] "C:/Users/HaroldFinch/Documents/R/win-library/3.4"
[2] "C:/Program Files/Microsoft/R Open/R-3.4.1/library"

我最终发现了原因。如R FAQ中所解释的那样,为了定义其主目录,R将首先使用已定义的R_USER环境变量,否则将使用已定义的HOME环境变量,否则将使用Windows的“个人”目录。

我的Windows配置没有定义R_USERHOME环境变量。因此,在DOS shell情况下,R使用我的Windows“个人”目录(C:/Users/HaroldFinch/Documents)。这很好,因为我的所有库都安装在那里(C:/Users/HaroldFinch/Documents/R/win-library/3.4)。

相比之下,cygwin 定义并导出了一个指向我的 cygwin 用户目录的 HOME 环境变量,其中缺少任何 R 相关内容。因此,从 cygwin 调用的 RScript 具有错误的 R 主目录,因此无法加载库。
可能有很多解决方法。我决定让我的 bash 脚本设置一个指向我的 Windows 用户目录的 R_USER 环境变量。
例如,如果我在 cygwin bash shell 中执行以下操作:
R_USER="C:/Users/HaroldFinch/Documents"
export R_USER
/cygdrive/c/Progra~1/Microsoft/ROpen~1/R-3.4.1/bin/x64/Rscript.exe -e ".libPaths()"

我看到了输出。
[1] "C:/Users/HaroldFinch/Documents/R/win-library/3.4"
[2] "C:/Program Files/Microsoft/R Open/R-3.4.1/library"

现在的输出与上面DOS shell示例完全相同。


0
另一个原因是packrat。如果您正在使用packrat运行,当您打开项目时,RStudio会为您打开它。但是RScript不会这样做,因此您需要在脚本中早期添加packrat::on()(在库调用之前)。

但是packrat在库文件夹中,该文件夹不易访问(win-library)。 - Jens

0

正如其他人已经指出的那样,问题在于Rscript.exe无法识别win-library文件夹。对我来说最简单的解决方案是通过添加以下内容来明确设置库文件夹的路径:

.libPaths("C:/Users/Benutzer1/Documents/R/win-library/4.0")

到我的程序。然后从win-library文件夹加载所有包,仍然可以从标准库文件夹加载包。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接