如何在循环中重复调用 R 并检索结果以在 SAS 中进行进一步处理

How to call R repeatedly in a loop and retrieve the results for further processing in SAS

我简化了代码来说明问题:

proc iml;
var=40;
call ExportMatrixToR(var, "var" );
submit / R;
sample<-sample(1:var, 50, replace=TRUE)
endsubmit;
call ImportDataSetFromR( "WORK.rdata", "sample" );
proc means data=rdata; 
output out=a;
run;

如何更好地控制 var,例如,如果我想尝试 var=(20,40,80,100,120...) 的不同值,如何像人们在宏中轻松完成一样?

请注意,rdata 是从 R 传输到 SAS 进行分析的,因此我们可能需要在 R 中创建不同的 data.frames,其名称取决于 var 的值. 有什么更简单的方法吗?

*******更新********

博士。 Wicklin,我桌上有你的书,太棒了。非常感谢您抽出宝贵时间回答问题。

我试过你的代码,它运行得很好,但我忘了说我的模拟数据有一个字符变量。提交的 R 代码如下所示:

 submit Ni / R;
 sample<-sample(1:&Ni, 50, replace=TRUE)   
 group<-rep(LETTERS[1:2],25)
 df<-data.frame(sample, group)
 endsubmit;

我试图解决您的代码以适应此功能,但 SAS 日志一直显示 "Variable group has type inconsistent with the data set"。你能帮忙吗?


*******更新 2**************


    proc iml;
    N = do(20, 120, 20);
    ID = 1; sample = .; group="";     
    create rdata var {ID "sample" "group"}; /* open data set for writing */
    do i = 1 to ncol(N);
    Ni = N[i];    /* get the i_th parameter; pass in on the SUBMIT statement */
       submit Ni / R;
     sample<-sample(1:&Ni, 50, replace=TRUE)   
     group<-rep(LETTERS[1:2],25)
       endsubmit;
    call ImportMatrixFromR(sample, "sample"); 
    call ImportMatrixFromR(group, "group"); 
       ID = j(nrow(sample), 1, i);   /* also save ID variable */
       append;              /* write IML data to SAS data set */
    end;
    close rdata;
    quit;

    proc means data=rdata; 
    by ID;        /* analyze all the results in a single call */
    output out=a;
    run;`

我假设您想按顺序尝试这些值,就像在循环中一样?如果是这样,您的问题可能更好地表述为 "how to call R repeatedly in a loop and retrieve the results for further processing in SAS."

首先,阅读文章"Twelve advantages to calling R from the SAS/IML language." 第一项描述了如何在循环中调用R并提供了一个例子。第三项显示了如何将参数从 SAS 传递到 R。

接下来,阅读文章"Simulation in SAS: The slow way or the BY way",其中介绍了如何构建SAS数据集,以便您可以高效地进行重复计算。结合这两个想法导致以下程序结构:

  1. 在IML中创建一个循环并重复调用R。或者,您可以 发送参数向量并在 R 中进行循环。第二个 方法可以更有效,但第一个匹配你的例子 更好,所以让我们选择那个选项。
  2. 每次分析后,检索结果。您可以将结果写入 SAS 数据集并包含一个 ID 变量,该变量将被 在下一步中用作 BY 变量。
  3. 您现在有一个包含 k 个结果的 SAS 数据集,每个结果都由一个指示变量标识。调用 SAS 过程 (PROC MEANS 在你的例子中)来分析每个结果。

这是一个例子:

proc iml;
N = do(20, 120, 20);
ID = 1; sample = .;     /* we will write a numeric variable */
create rdata var {ID "sample"}; /* open data set for writing */
do i = 1 to ncol(N);
   Ni = N[i];    /* get the i_th parameter; pass in on the SUBMIT statement */
   submit Ni / R;
      sample<-sample(1:&Ni, 50, replace=TRUE)   # access parameter in R
   endsubmit;
   call ImportMatrixFromR(sample, "sample"); /* create IML var; copy from R */
   ID = j(nrow(sample), 1, i);   /* also save ID variable */
   append;              /* write IML data to SAS data set */
end;
close rdata;
quit;

proc means data=rdata; 
by ID;        /* analyze all the results in a single call */
output out=a;
run;

在程序中,我对向量 {20, 40, 60,...} 进行了硬编码。您同样可以从宏变量或输入数据集中获取这些值。例如

data NValues;
input Vals @@;
datalines;
20 40 60 80 100 120
;

proc iml;
use NValues; read all var "Vals"; close;
N = T( Vals );
/* ...etc ... */