SAS:循环数据集,为第i行创建临时数据步骤,执行一些proc / temp数据,将结果返回到第一个数据集

时间:2013-10-08 21:15:32

标签: sas

所以我有一个“dataset_a”,如下所示:

Name  Month
Dick  Aug
Dick  Sep
Dick  Oct
Jane  Aug
Jane  Sep
...

还有一些像这样的更大的“dataset_b”:

Name  Day        X     Y
Dick  12-Jul-13  14.8  2.3
Jane  05-Sep-13  12.2  2.0
Dick  02-Aug-13  15.1  3.2
Dick  07-Aug-13  14.5  3.0
Jane  05-Aug-13  12.8  2.5
Dick  08-Aug-13  14.5  3.0
Dick  10-Aug-13  13.5  2.3
Jane  31-Jul-13  13.0  2.2
...

我想迭代它,对于“dataset_a”中的每一行,执行一个数据步骤,从“dataset_b”获取相应的记录并将它们放入临时数据集 - “temp”,让我们调用它。然后我需要在“temp”上做一个proc reg并将结果(row-vector-style)粘贴回“dataset_a”,如下所示:

Name  Month Parameter-est.-for-Y p-value  R-squared
Dick  Aug   Some #               Some #   Some #
Dick  Sep   Some #               Some #   Some #
Dick  Oct   Some #               Some #   Some #
Jane  Aug   Some #               Some #   Some #
Jane  Sep   Some #               Some #   Some #
...

这里有一些代码/伪代码来说明我的需求:

for each row in dataset_a
    data temp;
    set dataset_b; where name=['i'th name] and month(day)=['i'th month]; 
    run;
    proc reg /*noprint*/ alpha=0.1 outest=[?] tableout; model X = Y; run;
    /*somehow put these regression results back into 'i'th row of dataset_a*/
next

如果没有意义,请发表评论。非常感谢提前!

1 个答案:

答案 0 :(得分:4)

有效的方法与您列出的方法有所不同。在您展示的特定实例中,最有效的方法是使用格式将Day值分组为Months,并运行回归by name day,假设回归遵循格式(如果不是,则创建新变量{{ 1}}并使用格式指定。

例如:

month

或者

data for_reg/view=for_reg;
set dataset_b;
month=put(day,MONNAME3.);
run;

然后

proc datasets lib=work;
modify dataset_b;
format day MONNAME3.;
quit;

然后根据需要将输出数据集与proc reg data=for_reg; by name month; *or if using the other one, by name day; **other proc reg statements**; run; 合并。它将运行proc reg,就好像你为每个名称/月份组合运行一次,但是所有这一切都在一个调用中,一个遍历数据。


如果dataset_a不尊重群体(我认为确实如此,但谁知道),最好的解决办法仍然是做这样的事情;编写一个宏来运行带有PROC REGname参数的proc reg,并从month调用宏。然后生成公共输出文件(或将dataset_a它们放入宏中的单个主输出数据集中),并在最后需要时将结果合并到proc append

这样的东西
dataset_a

如果它只有这两个变量,你最后可能不需要在%macro run_procreg(name=,month=); data for_run/view=for_run; set dataset_b; where name=&name. and put(day,MONNAME3.)=&month.; run; proc reg data=for_run; *other stuff*; output out=tempdataset; *or however you create your output; run; proc append base=master_output data=tempdataset force; run; %mend run_procreg; proc sql; select cats('%run_procreg(name=',name,',month=',month,')') into :macrocalllist separated by ' ' from dataset_a; quit; &macrocalllist; data fin; merge dataset_a (in=a) master_output(in=b); by name month; run; 上合并。这比使用dataset_a的一次调用慢得多,但如果有必要,这就是这样做的方式。

您还可以在datastep中使用by来驱动上面的宏列表 - 这几乎是与您声明的伪代码最相似的概念,它几乎相同 - 但它不会将信息返回给数据step(在数据步骤完成后执行),它比上述方法稍微麻烦一些。在FCMP语言中还有9.3 + call execute允许你更接近你想要的东西,但我不太清楚它是否足以解释或知道它确实满足你的需求