如何在循环中重复调用 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数据集,以便您可以高效地进行重复计算。结合这两个想法导致以下程序结构:
- 在IML中创建一个循环并重复调用R。或者,您可以
发送参数向量并在 R 中进行循环。第二个
方法可以更有效,但第一个匹配你的例子
更好,所以让我们选择那个选项。
- 每次分析后,检索结果。您可以将结果写入 SAS 数据集并包含一个 ID 变量,该变量将被
在下一步中用作 BY 变量。
- 您现在有一个包含 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 ... */
我简化了代码来说明问题:
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数据集,以便您可以高效地进行重复计算。结合这两个想法导致以下程序结构:
- 在IML中创建一个循环并重复调用R。或者,您可以 发送参数向量并在 R 中进行循环。第二个 方法可以更有效,但第一个匹配你的例子 更好,所以让我们选择那个选项。
- 每次分析后,检索结果。您可以将结果写入 SAS 数据集并包含一个 ID 变量,该变量将被 在下一步中用作 BY 变量。
- 您现在有一个包含 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 ... */