7

我正在尝试使用命令行参数从命令行运行 R。这包括传入一些文件路径作为在脚本中使用的参数。大多数情况下这一切都有效,但有时路径中有空格并且 R 不理解。

我正在运行以下形式:

R CMD BATCH --slave "--args inputfile='C:/Work/FolderWith SpaceInName/myinputfile.csv' outputfile='C:/Work/myoutputfile.csv'" RScript.r ROut.txt

R抛出一个文件说

Fatal error: cannot open file 'C:\Work\FolderWith': No such file or directory

所以很明显,我的单引号不足以告诉 R 将引号内的所有内容作为参数值。我在想这意味着我应该找到一种--args使用逗号分隔的方法,但我找不到这样做的方法。我确定这很简单,但我在文档中没有找到任何内容。

当前脚本非常基本:

ca = commandArgs(trailingOnly=TRUE)
eval(parse(text=ca))
tempdata = read.csv(inputFile)
tempdata$total = apply(tempdata[,4:18], 1, sum)
write.csv(tempdata, outputFile, row.names = FALSE)

万一它是相关的,我正在为此使用 Windows,但它似乎不是 cmd 提示问题。

4

3 回答 3

3

使用eval(parse())可能不是解析命令行参数的最佳和最有效的方法。我建议使用类似的包optparse来为你做解析。解析命令行 args 已经解决了,不需要重新实现。我可以想象这可以解决您的问题。虽然,路径名中的空格一开始是个坏主意。

或者,您可以采用非常简单的方法并传递如下参数:

R CMD BATCH --slave arg1 arg2

您可以在哪里检索它们,例如:

ca = commandArgs(TRUE)
arg1 = ca[2]
arg2 = ca[3]

这避免了eval(parse我认为导致问题的原因。最后,您可以尝试像这样逃离空间:

R CMD BATCH --slave "C:/spam\ bla"

你也可以Rscript试一试,R CMD BATCH似乎不如Rscript.

于 2012-12-05T11:14:53.283 回答
1

这篇文章有很多相似之处: R command line passing a filename to script in arguments (Windows)

此外,这篇文章与操作系统非常相关。我的回答仅适用于 Windows。

可能您正在寻找的是RScript.exe而不是R.exe. 后者对空格没有问题:path\to\RScript "My script.r".

一件无聊的事情可能是RScript每次更新 R 时搜索或设置路径并执行此操作。

在我的搜索路径中的便利脚本中,我编写了一个小工具来运行 RScript 而不用担心路径。以防万一有人感兴趣:

@echo off
setlocal 


::Get change to file dir par (-CD must be 1st par)
::================================================
Set CHANGEDIR="F"
If /I %1 EQU -cd  (
 Set CHANGEDIR="T"
 SHIFT        
)       

::No args given
::=============
If [%1] EQU [] GoTo :USAGE 

::Get R path from registry 
::========================
:: may check http://code.google.com/p/batchfiles for updates on R reg keys
Call :CHECKSET hklm\software\R-core\R  InstallPath
Call :CHECKSET hklm\software\wow6432Node\r-core\r InstallPath
if not defined RINSTALLPATH echo "Error: R not found" & goto:EOF

::Detect filepath when arg not starting with "-" 
::==============================================

::Note the space after ARGS down here!!!
Set ARGS= 
:LOOP          
if [%1]==[] (GoTo :ELOOP)
Set ARGS=%ARGS% %1
::Echo [%ARGS%] 

Set THIS=%~1
if [%THIS:~0,1%] NEQ [-] (Set FPATH=%~dp1)

SHIFT          
GoTo :LOOP
:ELOOP        
::echo  %FPATH%


::Run Rscript script, changing to its path if asked
::=================================================
If %CHANGEDIR%=="T" (CD %FPATH%)
Echo "%RINSTALLPATH%\bin\Rscript.exe" %ARGS%
"%RINSTALLPATH%\bin\Rscript.exe" %ARGS%



endlocal 
:: ==== Subroutines ====
GoTo :EOF  

:USAGE       
Echo USAGE:
Echo  R [-cd] [RScriptOptions] Script [ScriptArgs]

Echo.          
Echo  -cd changes to script dir. Must be first par. 
Echo  To get RScript help on options etc.:
Echo  R --help

GoTo :EOF  


:CHECKSET  
if not defined RINSTALLPATH for /f "tokens=2*" %%a in ('reg query %1 /v %2 2^>NUL') do set RINSTALLPATH=%%~b
GoTo :EOF  

该脚本在运行之前打印实际的 RScript 调用行。

请注意,添加了一个参数 ,-cd以自动更改为脚本目录。事实上,从 R 内部猜测脚本路径并不容易(并用 设置它setwd()),以便调用其他脚本或读/写放置在同一路径(或相对路径)中的数据文件。

这个 ( -cd) 可能会使您的其他命令参数变得多余,因为您可能会发现直接从脚本内部调用它们很方便。

于 2012-12-05T14:22:48.713 回答
1

作为@PaulHimestra 的改进,您可以在这里回答如何使用 Rscript :

您创建一个 launcher.bat ,

echo off
C:
PATH R_PATH;%path%
cd DEMO_PATH
Rscript youscript.R arg1 arg2
exit

使用 R_PATH 类似于 C:/Program Files/R/R-version

于 2012-12-05T11:35:44.703 回答