我编写了一个接受变量列表的宏,使用每个变量作为预测器运行proc混合模型,然后将结果导出到附加了变量名称的数据集。我试图找出如何堆叠单个数据集中的所有变量的结果。
这是宏:
%macro cogTraj(cog,varlist);
%let j = 1;
%let var = %scan(&varlist, %eval(&j));
%let solution = sol;
%let outsol = &solution.&var.;
%do %while (&var ne );
proc mixed data = datuse;
model &cog = &var &var*year /solution cl;
random int year/subject = id;
ods output SolutionF = &outsol;
run;
%let j = %eval(&j + 1);
%let var = %scan(&varlist, %eval(&j));
%let outsol = &solution.&var.;
%end;
%mend;
/* Example */
%cogTraj(mmmscore, varlist = bio1 bio2 bio3);
结果将是Solbio1,Solbio2和Solbio3的创建。
我创建了一个包含" varlist"的宏变量。 (理想情况下,我想输入一个宏变量列表作为参数,但我还没有弄清楚如何处理范围):
%let biolist = bio1 bio2 bio3;
我想通过使用文本操作来添加" Sol"来堆叠Solbio1,Solbio2和Solbio3。到每个变量的开头。我在任何数据步骤或宏之外尝试了以下内容:
%let biolistsol = %add_string( &biolist, Sol, location = prefix);
没有成功。
最终,我想做这样的事情;
data Solbio_stack;
set %biolistsol;
run;
结果是Solbio1,Solbio2和Solbio3堆叠在一起的单个数据集,但我确定我没有正确的语法。
任何人都可以帮我解决文本字符串/数据集堆叠问题吗?如果我能弄清楚如何更改宏以接受%biolist作为参数,而不是将列表变量写为宏的参数,我会非常高兴。
答案 0 :(得分:1)
我会采用不同的方法。解决问题的一个好方法是使用数据集驱动它;这就是SAS擅长的,真的,这很容易。
首先,构建一个数据集,其中包含您正在运行此变量的每个变量的行,以及包含变量名称的变量name
(每行一个)。如果您使用一个特定数据集中的一组变量,则可以使用PROC CONTENTS
或sashelp.vtable
或dictionary.tables
来构建此项。它也可以来自您导入的电子表格,文本文件或其他任何内容 - 或者只是作为数据表写入,如下所示。
因此,您的示例将包含此数据集:
data vars_run;
input name $ cog $;
datalines;
bio1 mmmscore
bio2 mmmscore
bio3 mmmscore
;;;;
run;
如果你的'cog'相当一致,你不需要把它放在数据中,如果它可能会改变你可能在数据中也有一个变量。我在上面的例子中做了包括它。
然后,你编写宏,以便在PROC MIXED
上进行一次传递 - 即%do
循环的内部部分。
%macro cogTraj(cog=,var=, sol=sol);
proc mixed data = datuse;
model &cog = &var &var*year /solution cl;
random int year/subject = id;
ods output SolutionF = &sol.&var.;
run;
%mend cogTraj;
我把& sol的默认值放在那里。现在,您从数据集中的每一行生成一次对宏的调用。您还可以生成溶胶组列表。
proc sql;
select cats('%cogTraj(cog=',cog,',var=',name,',sol=sol)')
into :callList
sepearated by ' '
from have;
select cats('sol',name') into :solList separated by ' '
from have;
quit;
接下来,运行宏:
&callList.
然后你可以这样做:
data sol_all;
set &solList.;
run;
全部完成,并且更少的宏变量解析,这是一个混乱和烦人。