2013-06-20 47 views
4

我想使用evaluate軟件包模擬執行(大量)r腳本,同時使用評估記錄輸出。評估旨在完成這一工作,它幾乎可以直接使用。但是,使用Rscript時,用戶通過命令行--args傳遞參數,這些參數在R中使用base::commandArgs函數進行檢索。從R會話中設置-args的值

是否有任何明智的方法可以在正在運行的R會話中覆蓋--args的值,使得使用base::commandArgs()的R腳本可以按預期工作,而無需修改腳本本身?

+0

爲什麼不在您當前的會話中設置參數?即輸入控制檯'args < - c(arge1,arg1,...)' – agstudy

+0

我希望它能用於第三方r腳本。 – Jeroen

+0

我不明白你的觀點。我的意思是你只是在你的腳本中註釋了一行'#args < - commandArgs(TRUE)',那麼你在你的控制檯中定義了'args',並且你的'source('script_name')''。 – agstudy

回答

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()更改之前會返回向量。

+0

即使所有這些味道都不是很好:)但很好的知道如何破解一些R'C代碼。 – agstudy

+0

太棒了。謝謝! – Jeroen

1

在你的腳本的頂部設置commandArgsTRUE,如果你不通過命令行上的任何變量將是長度爲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") 
+2

@agstudy感謝與'simpleWarning'的提示,我以前不知道這件事。乾杯! –

+1

這並不能真正解決我的問題。我正在執行(很多)第三方提供的r-scripts,期望通過'commandArgs'輸入。 – Jeroen

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>