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

在R会话中设置--args的值,r,evaluate,cran,rscript,R,Evaluate,Cran,Rscript,我想使用evaluate包模拟执行(大量)r脚本,同时使用evaluate记录输出。Evaluate的设计正是为了做到这一点,它几乎是开箱即用的。但是,当使用Rscript时,用户通过命令行--args传递参数,这些参数使用base::commandArgs函数在R中检索 是否有任何合理的方法可以在运行的R会话中覆盖--args的值,这样使用base::commandArgs()的R脚本就可以按预期工作,而无需修改脚本本身?在脚本顶部,您将commandArgs设置为TRUE,如果您没有在命令行

我想使用
evaluate
包模拟执行(大量)r脚本,同时使用evaluate记录输出。Evaluate的设计正是为了做到这一点,它几乎是开箱即用的。但是,当使用Rscript时,用户通过命令行
--args
传递参数,这些参数使用
base::commandArgs
函数在R中检索


是否有任何合理的方法可以在运行的R会话中覆盖
--args
的值,这样使用
base::commandArgs()
的R脚本就可以按预期工作,而无需修改脚本本身?

在脚本顶部,您将
commandArgs
设置为
TRUE
,如果您没有在命令行上传递任何内容,那么变量的长度将为
0
,因此当您没有实际传递命令行参数时,请使用
if
语句来分配一些值。如果需要小心使用默认值,则可以在使用命令行参数的默认值时设置一个标记以打印消息

args <- commandArgs(TRUE)
argDefault <- FALSE
if( length(args) == 0 ){
   args <- whatever you want
   argDefault <- TRUE
}
res <- 2 * args[1]
if( argDefault )
      simpleWarning(message="No command args were passed: Use of default values")  

args我深入研究了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()
将返回该向量,直到您更改它。

以下是@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()
*/

为什么不在当前会话中设置参数?ie在控制台中键入
args我希望它能用于第三方r脚本。我不明白你的意思。我的意思是,您只需在脚本
#args中注释一行,假设我有10000000个来自其他人的脚本,这些脚本可能在某个地方使用或不使用
commandArgs
,我想运行它们。我不能假设任何事情。如果要运行10000000个脚本,请将此信息添加到问题中。还有,如何测试10000000个脚本的参数。@agstudy感谢使用
simpleWarning
提供的提示,我以前不知道这一点。干杯这并不能真正解决我的问题。我正在执行(很多)第三方提供的r脚本,这些脚本期望通过
commandArgs
进行输入。即使这一切闻起来不是很好:),但很高兴知道如何破解一些r'C代码。
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>