在R会话中设置--args的值

时间:2013-06-20 06:20:55

标签: r evaluate cran rscript

我想使用evaluate包来模拟执行(大量)r脚本,同时使用evaluate记录输出。 Evaluate旨在完成这项工作,它几乎可以开箱即用。但是,在使用Rscript时,用户通过命令行--args传递参数,使用base::commandArgs函数在R中检索这些参数。

有没有明智的方法可以在正在运行的R会话中覆盖--args的值,这样使用base::commandArgs()的R脚本可以按预期工作而无需修改脚本本身?

3 个答案:

答案 0 :(得分:10)

这是@spacedman的答案,它是一个简单的基于Rcpp的实现。我们必须在矢量上做一些体操,才能把它变成char**格式:

#include "Rcpp.h"
#include "R_ext/RStartup.h"

// [[Rcpp::export]]
void setCmdArgs(std::vector<std::string> x) {
  std::vector<char*> vec(x.size());
  for (unsigned int i=0; i<x.size(); i++) 
    vec[i] = const_cast<char*>(x[i].c_str());
  R_set_command_line_arguments(x.size(), static_cast<char**>(&(vec[0])));
}

/*** R
setCmdArgs(c("hello", "world"))
commandArgs()
setCmdArgs(c("good", "bye", "my", "friend"))
commandArgs()
*/

如果您将其保存在文件中并通过一次调用sourceCpp()将其拉入,则R 底部的片段也被执行:

R> sourceCpp("/tmp/spacedman.cpp")

R> setCmdArgs(c("hello", "world"))

R> commandArgs()
[1] "hello" "world"

R> setCmdArgs(c("good", "bye", "my", "friend"))

R> commandArgs()
[1] "good"   "bye"    "my"     "friend"
R> 

答案 1 :(得分:6)

我深入研究了R的内脏,并想出了一些可以玩的臭肠。

命令行从C的argc / argv复制到源代码中使用此函数的全局C变量:

void R_set_command_line_arguments(int argc, char **argv)

所以我们需要一个小的C包装器来绕过第一个参数不是指针的事实:

#include "R.h"
#include "R_ext/RStartup.h"
void set_command(int *pargc, char **argv){
  R_set_command_line_arguments(*pargc, argv);
}

以通常的方式编译:

R CMD SHLIB setit.c

加载,致电:

> dyn.load("setit.so")
> commandArgs()
[1] "/usr/lib/R/bin/exec/R"
> invisible(.C("set_command",as.integer(2),c("Foo","Bar")))
> commandArgs()
[1] "Foo" "Bar"

从那时起commandArgs()将返回该向量,直到您更改它为止。

答案 2 :(得分:1)

在脚本的顶部,您将commandArgs设置为TRUE,如果您未在命令行上传递任何内容,则变量的长度为0,因此请使用{ {1}}语句在您实际未传递命令行参数时分配一些值。如果您需要注意使用默认值,可以设置一个标志,以便在使用命令行参数的默认值时打印消息。

if