SAS学习笔记 宏变量赋值

SAS给宏变量赋值大体来说其实就3种方式:%let语句、data步中的call symput语句proc sql过程中into语句
这里根据变量和观测的数量分情况进行如下讨论,即:

  • 单变量单观测变单宏变量
  • 单变量单观测变多宏变量
  • 单变量多观测变多宏变量

单变量单观测变单宏变量

提出问题如下:

/*problem1:将组名信息赋值给宏变量group,各组之间\分割,单变量一观测变一宏变量*/

数据集如下:

data example1;
    group  = "太极组\围棋组\古筝组\书法组";
run;
example1数据集

分别使用如下3种方法进行宏变量赋值:

/*method1: let statement*/

%let group1 = 太极组\围棋组\古筝组\书法组;

%put &group1.;
日志信息

/*method2:data步 call symput statement*/
data _null_;
    set example1;
    call symput("group2",group);
run;

%put &group2.;

日志信息

/*method3:proc sql statement*/

proc sql;
     select group  into: group3
     from example1 
     ;
quit;

%put &group3.;
日志信息

  • 说明
proc sql;
/*    create table macros as*/
    select *
    from dictionary.macros
    ;
quit;

上述语句是获得环境中macros变量信息的语句,很实用。

在单变量赋值单宏变量时,%let语句相比其他两种要简单,不必基于数据集;而proc sql语句则必须基于数据集中的变量产生;call symput则均可以实现。


单变量单观测变多宏变量

  • 问题
/*problem2:将组名信息分别依次赋值给宏变量term1,term2,...,单变量一观测变多宏变量*/
  • 数据集如下:
data example2;
    group  = "太极组\围棋组\古筝组\书法组";
run;
xample2数据集

分别使用如下3种方法进行宏变量赋值:

/*method1: let statement*/
%let term1_1 = 太极组;
%let term1_2 = 围棋组;
%let term1_3 = 古筝组;
%let term1_4 = 书法组;

%macro batch;
%do i = 1 %to 4;
    %let _term1_&i. = %qscan("太极组\围棋组\古筝组\书法组" , &i. , "\");
%end;

proc sql;
/*    create table macros as*/
    select *
    from dictionary.macros
    where scope = "BATCH"
    ;
quit;
%mend;
%batch;
batch宏批量处理后打印结果

/*method2:data步 call symput statement*/

data _null_;
   set example2
    do i = 1 to 4;
        call symput(cats("term2_", put(i , best.)) , scan(group , i, "\") );
    end;
run;
打印结果

/*method3:proc sql statement*/
data m3;
   set example2
    array term (4) $ term1 - term4;
    do i =1 to 4;
        term(i) = scan(group , i, "\") ;
    end;
run;

proc sql;
     select  term1, term2, term3, term4  into :term3_1  ,:term3_2 ,:term3_3,:term3_4
     from m3
     ;
quit;

proc sql;
/*    create table macros as*/
    select *
    from dictionary.macros
    ;
quit;
打印结果

  • 说明
  1. 这种情况就可以看出 %let语句的劣势了,无法批量操作,为了批量操作我写了个简单宏才实现;
  2. call symput语句的实现则很简单,这是因为只涉及到单个变量的操作,是data步的优势所在,代码量很少;
  3. proc sql给宏变量赋值的优势在这里体现的不明显,但是也可以看出它针对数据集层面,批量化宏变量赋值操作的便捷性。

单变量多观测变多宏变量

  • 问题
/*problem3:将分组变量中组名观测依次赋值给宏变量term1,term2,...,单变量多观测变多宏变量*/
  • 数据集
data example3;
    length group $200.;
    input group;
cards;
太极组
围棋组
古筝组
书法组
;
proc print;
run;

example3打印结果

  • 使用3种方法赋值宏变量
/*method1:%let statement*/

proc transpose data= example3 out=_out3;
    var group;
run;

%macro m1;
    data test;
        set _out3;
        call symput("group" ,catx("\", of col1 - col4) );
    run;
    %do i = 1 %to 4;
       %let _1term_&i. = %qscan( "&group.", &i.,"\");
    %end;
    proc sql;
        create table macros as
        select *
        from dictionary.macros
        where scope = "M1"
        ;
    quit;
%mend;
%m1;
_out3输出
复制后宏变量结果输出

使用%let解决这个问题,需要先转置,使问题变为基于变量,也就是列,弥补基础语句基于观测处理问题能力偏弱的短板
然后构建宏,在宏里还要再把数据集里的多个变量赋值为单个宏变量,这是因为%let是在变量层面解决问题的,数据集无处下爪;
之后使用循环,弥补%let批量处理问题的短板。


/*method2:call symput statement*/
proc transpose data= example3 out=_out3;
    var group;
run;

data M2;
    set _out3;
    array terms(4) col1 -col4;
    do i = 1 to 4;
        call symput(cats("_2term_", put(i , best.)),terms(i) );
    end;
run;

proc sql;
    select *
    from dictionary.macros
    ;
quit;
打印结果
  • 说明

可以看到,使用call symput解决这个问题,同样需要经历转置步骤转变为处理变量的问题;然后在data步使用数组循环,还是比较繁琐的。

  • proc sql的优势就体现出来了,一个代码块就达成目的,如下:

/*method3:proc sql statement*/
/*单变量多观测变多个宏变量*/
proc sql;
     select  group  into :_3term1 -: _3term99
     from example3
     ;
quit;

/*单变量多观测变一宏变量*/
proc sql;
     select  group  into :_3term separated by " "
     from example3
     ;
quit;

proc sql;
/*    create table macros as*/
    select *
    from dictionary.macros
    ;
quit;
打印结果

  • 说明
  1. 这种情况%let的实现一样要借助于宏,并且因为涉及到了数据集层面的操作,%let就更加不太擅长了;
  2. 同时,call symput的实现也不太容易,SAS data长于变量操作弱于观测操作的弊端便体现出来了。
  3. 在这种情况下,proc sql的批量化和观测层面操作的优势便体现出来了,如果是有多变量多观测赋值多宏变量的情况,那proc sql的优势就会更加明显了;

proc sql给宏变量赋值的情况大致可以分为如下几种情况

  1. 单变量单个观测值赋值给单个宏变量:proc sql; select var into :mvar from dtin ; quit;,这种情况用proc sql不具有优势;

  1. 多变量单观测值赋值给多个宏变量:proc sql; select var1, var2, var3, var4 into :mvar1, mvar2, mvar3, mvar4 from dtin ; quit;

  1. 单变量多观测赋值给多个宏变量:proc sql; select var1into :mvar1 -:mvar99 from dtin ; quit;,其中,mvar99中的数值设置的较大值,是在未知观测值数量时的简便做法;

  1. 单变量多观测赋值给单个宏变量:proc sql; select var1into :mvar separated by "sep" from dtin ; quit;,其中,sep是分隔符;

  1. 多变量多观测值赋值给多个宏变量:proc sql; select var1, var2, var3, var4 into :var1m1 -:var1m99, var2m1 -:var2m99, var3m1 -:var3m99, var4m1 -:var4m99 from dtin ; quit;,其中的4个变量均有多个观测值;
  • 举例
proc sql;
    select name, weight, height into :name1 -:name99,
     :weight1 -:weight99, 
     :height1 -: height99
    from sashelp.class(where = (sex = "女"))
    ;
quit;
情况5 结果输出

  1. 多变量多观测值赋值给多个宏变量,但变量内观测值拼接:proc sql; select var1, var2, var3, var4 into :var1m1 -:var1m99, var2m1 -:var2m99, var3m1 -:var3m99, var4m1 -:var4m99 from dtin ; quit;,其中的4个变量均有多个观测值;
proc sql;
    select name, weight, height into :name separated by " ", :weight separated by " " ,:height separated by " "
    from sashelp.class(where = (sex = "女"))
    ;
quit;
情况6 举例输出

总结

不涉及数据集的单变量的宏变量赋值%let很实用;
基于数据集且多在变量层面操作call symputproc sql均适用;
基于数据集且涉及多个变量和观测层面的操作proc sql比较有优势,其他两种实现起来就需要更多的代码量;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容