宏列表变量的文本操作,以使用自动名称堆栈数据集

时间:2014-06-18 17:47:24

标签: sas

我编写了一个接受变量列表的宏,使用每个变量作为预测器运行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作为参数,而不是将列表变量写为宏的参数,我会非常高兴。

1 个答案:

答案 0 :(得分:1)

我会采用不同的方法。解决问题的一个好方法是使用数据集驱动它;这就是SAS擅长的,真的,这很容易。

首先,构建一个数据集,其中包含您正在运行此变量的每个变量的行,以及包含变量名称的变量name(每行一个)。如果您使用一个特定数据集中的一组变量,则可以使用PROC CONTENTSsashelp.vtabledictionary.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;

全部完成,并且更少的宏变量解析,这是一个混乱和烦人。