在命令行(终端)上使用R脚本的最佳方法是什么?


115

使用R脚本从命令行进行简单绘图非常方便。但是,从bash脚本运行R根本不方便。理想可能是这样的

#!/path/to/R
...

要么

#!/usr/bin/env R
...

但我无法完成任何一项工作。

另一种选择是将脚本纯粹保留在R中,例如script.R,然后使用R --file=script.R或类似名称调用脚本。但是,脚本有时会依赖晦涩的命令行开关,此时,部分代码存在于脚本之外。例如:通过本地.Rprofile将东西从bash偷偷潜入R中,那么所需的开关就--vanilla意味着所有东西--no-init-file

另一个选择是bash脚本,用于存储R标志并且可以轻松执行,然后调用R脚本。问题在于这意味着单个程序仅被拆分为两个文件,这些文件现在必须保持同步,一起传输到新计算机等。

我目前最不喜欢的选项是将R嵌入到bash脚本中:

#!/bin/bash
... # usage message to catch bad input without invoking R
... # any bash pre-processing of input
... # etc
R --random-flags <<RSCRIPT
# R code goes here
RSCRIPT

一切都在一个文件中。它是可执行文件,可以轻松处理参数。问题在于,像这样将bash和R结合在一起,几乎消除了任何IDE不能彼此失败的可能性,并使我的心脏受了重伤。

有什么更好的方法我想念吗?

Answers:


132

内容script.r

#!/usr/bin/env Rscript

args = commandArgs(trailingOnly = TRUE)
message(sprintf("Hello %s", args[1L]))

第一行是射帮线。最佳做法是使用/usr/bin/env Rscript而不是对R安装的路径进行硬编码。否则,您可能会在其他计算机上破坏脚本。

接下来,使其可执行(在命令行上):

chmod +x script.r

从命令行调用:

./script.r world
# Hello world

1
是的,我认为这是这样做的“官方”方式。
弗兰克

5
Rscript --help从命令行运行将列出许多可以添加到shebang的有用选项,例如--vanilla
flodel 2012年

8
我们还要提及用于解析命令行的commandArgs函数和getoptand optparse包。这样,当从命令行运行时,参数和选项也可以传递给脚本。
flodel 2012年

1
请注意,这仅在以下情况下有效#!/usr/bin/Rscript(这不是 R脚本的标准做法)。
gentil '17


10

Miguel Sanchez的回应就是应该的方式。执行Rscript的另一种方式可以是“ env”命令来运行系统范围的RScript。

#!/usr/bin/env Rscript

1
不是“全系统”,而是env将允许您运行第一个Rscript在自己的FOUND $PATH,从而使一个实际运行的东西其他比全系统的/默认的Rscript(可能未安装/usr/whatever)。我建议使用envfor RRscriptstuff,因为这些尤其可能未安装在标准位置。(bash不过,通常可以安全地使用普通脚本#!/bin/bash。)
michael

@michael不,关于Bash,您错了,这是危险的建议。唯一可以安全进行硬编码的是/bin/sh。其他所有内容都必须使用env查找。特别是,Bash通常在计算群集上已经过时,并且用户拥有自己的自定义安装(通常在~/.local/bin或在/softwareNFS挂载中共享)。同样,在MacOS,/bin/bash永远过时由于许可问题,以及最新的Bash是更常见位于/usr/local/bin/bash(我知道您的评论是3岁,但是这是相当重要的。)
康拉德·鲁道夫

不,对不起,那根本不是事实。不过,您对此事有很强烈的意见,因此我不会对此问题进行辩论。如果/bin/sh在任何情况下使用都不是“危险的”,那么您必须承认同样可以说/bin/bashenv由于PATH不同用户的设置可靠/不一致,因此使用更加不可预测,但是每个R用户实际上都可能需要此行为,而bash脚本则不需要。最后,对于CI / cloud调用较新的bash脚本,只需使用/path/to/my/bash myscript或明确设置路径并使用即可调用它们env script。EOT
michael

9

#!/path/to/R因为R本身是脚本,所以不起作用,因此execve感到不高兴。

我用 R --slave -f script


4
对不经意的读者来说很方便:如果您想知道的话,很多答案都早于Rscript(和littler)。
迈克尔

@michael这里没有答案早于Rscript,该脚本于2007年随R 2.5.0发布。
康拉德·鲁道夫


4

这有效,

#!/usr/bin/Rscript

但是我不知道如果您的计算机上安装了多个R版本,会发生什么情况。

如果你这样做

#!/usr/bin/env Rscript

它告诉解释器只使用路径上最先出现的R。


2

如果用于执行脚本的程序需要参数,则可以将其放在#!的末尾。线:

#!/usr/bin/R --random --switches --f

不知道R,我无法正确测试,但这似乎可行:

axa@artemis:~$ cat r.test
#!/usr/bin/R -q -f
error
axa@artemis:~$ ./r.test
> #!/usr/bin/R -q -f
> error
Error: object "error" not found
Execution halted
axa@artemis:~$

2

只是要添加到此帖子的注释。的更高版本R似乎已经Rscript有所掩饰。对于2015年1月下载的OSX上的R 3.1.2-1,我Rscript

/sw/Library/Frameworks/R.framework/Versions/3.1/Resources/bin/Rscript

因此,#! /sw/bin/Rscript我需要在脚本顶部使用以下内容,而不是类似。

#! /sw/Library/Frameworks/R.framework/Versions/3.1/Resources/bin/Rscript

locate Rscript可能对您有所帮助。


该答案可能会有所帮助,因为不清楚OP指的是哪个平台(* nix或Mac OS)。稍作修改(希望格式化代码并删除道歉的开头),这将是对此处答案的一个很好的补充。
BenBarnes

2
这是#!/usr/bin/env RscriptR脚本中使用而不是硬编码路径(并将该长路径添加到您的路径中$PATH)的另一个原因
michael

0

您可能要使用python的rpy2模块。但是,“正确”的方法是使用R CMD BATCH。您可以对其进行修改以写入STDOUT,但默认设置是写入.Rout文件。请参见下面的示例:

[ramanujan:~]$cat foo.R
print(rnorm(10))
[ramanujan:~]$R CMD BATCH foo.R
[ramanujan:~]$cat foo.Rout

R version 2.7.2 (2008-08-25)
Copyright (C) 2008 The R Foundation for Statistical Computing
ISBN 3-900051-07-0

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

[Previously saved workspace restored]


 ~/.Rprofile loaded.
Welcome at  Fri Apr 17 13:33:17 2009
> print(rnorm(10))
 [1]  1.5891276  1.1219071 -0.6110963  0.1579430 -0.3104579  1.0072677 -0.1303165  0.6998849  1.9918643 -1.2390156
>

Goodbye at  Fri Apr 17 13:33:17 2009
> proc.time()
   user  system elapsed
  0.614   0.050   0.721

注意:您需要尝试使用--vanilla和其他选项来删除所有启动项。


0

尝试使用smallR在命令行中编写快速的R脚本:

http://code.google.com/p/simple-r/

r目录中的命令)

使用smallR从命令行进行绘制如下所示:

r -p file.txt

2
除了这个(看起来已经死了),littler肯定会被优先考虑(因为它还活着);或者,仅使用Rscript(实际上是在littler创建之后才出来的。)
michael

-1

以下在Windows上使用MSYS bash对我有用-我的Linux机器上没有R,因此无法在那里尝试。您需要两个文件-第一个名为runr的文件使用文件参数执行R

# this is runr
# following is path to R on my Windows machine
# plus any R params you need
c:/r/bin/r --file=$1

您需要使用chmod + x runr使其成为可执行文件。

然后在您的脚本文件中:

#!runr
# some R commands
x = 1
x

注意#!运行程序行可能需要包含运行程序的完整路径,具体取决于您如何使用命令,如何设置PATH变量等。

不漂亮,但似乎确实有效!


1
那么需要不同参数的不同R脚本呢?从命令行将参数传递给R脚本怎么办?
blahdiblah
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.