欢迎光临散文网 会员登陆 & 注册

SAS Training Vol.6 你是不是也不想写代码?

2021-08-17 22:53 作者:陆震同学  | 我要投稿

你有没有觉得,SAS 中的宏有一种 R 的元编程的感觉?

对于规律的、重复性的 code,懒人都不想多写哪怕一行。要想省体力,就得花脑力。怎么减少重复性 programming?借助宏捷径。

我们今天来接触特定的几个情景。

情景一:label

需要我们写以下这么多可怕的 label statements:

咋办?一行行地复制粘贴替换么?你也不愿意干!

要生成这样一系列的带有共同 prefix 的行标识符标签,我们可以这样偷懒:

%macro label(n);
   %do i= 1 %to &n;
       label condid&i= "condition ID&i";
   %end;
%mend label;
%label(20)

嘿嘿,只要在 data 步里加这个 macro,你就摆脱了最原始的复制粘贴,还是挺爽的吧?

情景二:%goto statement

明白地告诉你:现在我在同一个 folder 底下有四个文件,分别名为 cty_1、cty_2、cty_3 和 cty_4,这四个文件里面的 layout 都一样。但是我就想读里面的三个,不读文件 cty_3,你咋整?是不是也要写成下面这样?

从今晚看了这篇推送开始,咱都有脾气了,要和这些 say goodbye,偷懒一下:

%macro read;
   %do i= 1 %to 4;
       %if &i= 3 %then
           %goto leslie;
       
       data cty_&i;
           infile "D:\NESUG\CTY_&I";
           input id f96 f97 f98;
       run;
       
       %leslie: %end;
%mend read;

这里借助了 %goto statement,这 4 个中第三个我们想做 specific 处理,就可以这样操作,让它跳出数据读取的循环之中。

是不是有懒人那味儿了?

情景三:symput routine、%eval、byte function

把情景二改一下:还是那四个文件,只不过我们想对应地输出三个分别名为 cty_A、cty_B 和 cty_D 的文件,还是任性地不想读第三个文件并输出。

%macro read;
   %do i= 1 %to 4;
       %if &i= 3 %then
           %goto leslie;
       
       data cty_&i;
           infile "D:\NESUG\CTY_&I";
           input id f96 f97 f98;
           call symput("N", byte(%eval(&i + 64)));
       run;
       data cty_&N;
           set cty_&i;
       run;
       
       %leslie: %end;
%mend read;

这里 symput routine 是为了动态地生成 macro variable N。另外,之所以加上 64,是因为利用 byte funciton 输出 A 时,A 在 ASCII 编码系统里排第 65 位。

这种批量化地操作是不是省时省力?

情景四:flag variable

我们在处理 raw data 时,经常需要根据一些 variables 的取值来给每个人建立一个 flag variable,来标识每个 subject 某种属性的类别情况,这个时候,macro 就显得非常好用了。

假设我们有这样的 condition,你要不要这样一个条件一个条件地筛,最后建立起一个 error1?

答案很显然,你也头晕。

%macro mdx(ndx, code);
   %do i= 1 %to &ndx-1;
       dx&i= "&code" or
   %end;
   dx&ndx= "&code"
%mend mdx;
if %mdx(15, E8710) then error1= 1;

看到这,相信你对宏已经有了一个初步的了解。


SAS Training Vol.6 你是不是也不想写代码?的评论 (共 条)

分享到微博请遵守国家法律