• sas宏变量与数据集之间的交互


    在目前的数据处理过程中,我们面对的处理对象主要是二位数据表即sas数据集,但是我们在写宏程序时,宏变量和红参数又是字符串的形式,所以我们需要探讨一下宏变量和红参数怎么和数据集之间进行交互。

    将数据集集名、变量名、变量值、变量label、变量类型等以单个值或者多个值拼接的形式传给宏变量。

    将宏变量的值作为生成数据集的代码与数据集代码进行拼接。

     转载注明出处:http://www.cnblogs.com/SSSR/p/6908521.html 

    一、生成宏变量的三种方式

    1.%let

    %let day=Friday;/*作为一些自定义变量*/
    %put dayis:&day;

    这里需要说明一下,Friday没有加引号,这个也是因为宏的目的是为了拼接程序,而在写程序中一般是没有引号的,只有在使用变量值的时候或者函数参数时才会有引号,当我们遇到这些时使用||进行拼接即可,或者使用"&var.",

    在双引号中&是生效的,但是在单引号中是不生效的。

    2.symput或symputx函数

    data步中产生新变量, 宏变量的命名规则按照普通sas宏变量的规则,但需要加上对称引号,两者的区别symputx被赋值数值时可以删除补空的首空格,其作用为trim+symput函数。

    若宏变量被赋的可以是文本常量,如call symput("gender","Imformation for male");文本需加引号,也可以是data步某变量的当前值如call symput("gender",sex);

    data test4;
    set sashelp.class;
    if Sex="M" then do ;
    output;
    call symput("gender","Imformation for male");
    end;
    run;
    proc print;
    title "&gender"; /*调用gender宏变量*/
    run;

     

    3.select into

    这个最常用的就是讲sas的数据集的变量名赋给宏变量,以供其他程序使用。

    data a;
    input name $ id sex $ num1 var1 $ num2 var2 $ var3 var4 $;
    cards;
    a 1 m 3 x 5 y 7 z
    ;
    run;
    proc print;
    run;

    /*这个是通过空格间隔的,在data步和proc步中使用*/
    proc sql;

    select name into :vars separated by ' '
    from dictionary.columns
    where memname='A';
    quit;

    /*这个是用逗号间隔的,在select语句中使用。*/
    proc sql;

    select name into :vars1 separated by ','
    from dictionary.columns
    where memname='A';
    quit;
    %put &vars.;
    %put &vars1.;

    二、在data步中使用宏变量

    1.symget

    该函数作为data步变量值与宏变量的桥梁,symget(day)是data步day变量的每个值作为一个宏变量,调用全局宏变量表的相应的宏变量的值。如day的day1值对应的宏变量day1的值为Monday,

    所有最后data 的day变量的day1为Monday。该函数的作用相当于if的作用,ifday=”day1” then day=”Monday”;使用上语句简单,不容易出错逻辑上的遗漏或重叠等错误。

    %let day1=Monday;
    %let day2=Tuesday;
    %let day3=Wednesday;
    data test3;
    input day $ plan : & $10.;
    day=symget(day);
    cards;
    day1 zoo
    day2 sea world
    day3 park
    ;
    run;

    2.将宏变量的值写入数据集

    下面的两个例子,如果我们定义%let a=1 q 2 w 3;则就是将宏变量的值存入数据集中的方法。

    这两个例子还解决了相同名称的数据集循环set的问题,不用首先写一个空数据集了。

    例子1:


    %macro test;
    %do i = 1 %to 5;
    %let x&i. = %scan(1 q 2 w 3,&i.);

    data collect;
    length x $20.;

    x = "&&x&i..";
    i = &i.;
    run;

    proc append base = all data = collect;
    quit;
    %end;
    %mend;
    %test;

    用append可以免去新建base数据集的麻烦;但是小心如果本身all就存在,他会把all直接拿来用。也可以用SQL的insert来插值。

    例子2:

    %macro test;
    %do i = 1 %to 5;
    %let x&i. = %scan(1 q 2 w 3,&i.);

    data collect;
    length x $20.;
    %if &i. > 1 %then %do;/*是否为第一次新建*/
    set collect end = last;
    output;

    if last then do;
    %end;
    x = "&&x&i..";
    i = &i.;
    output;

    %sysfunc(ifc(&i. > 1,end;,))
    run;
    %end;
    %mend;
    %test;

     这个里用了%if条件判断,是否为第一次新建数据。

    以下是第2次的宏解析出的语句:

    data collect;
    length x $20.;/*定义长度*/
    set collect end = last;/*end=last 就是对数据集最后一条记录打个标记,以判断是否到达最后一条观测。SAS 是行读入机制,如果读到最后一行这个标记为1否则为0*/
    output;/*使用这个output的原因,是因为在if语句中含有output,如果代码中有了output,那么所有的输出都要通过ouput显示输出,默认输出将会关闭,这里是set语句中的pdv一行一行的输出。*/
    if last then do;/*判断如果是最后一条记录了,则执行下面的语句。*/
    x = "q";
    i = 2;
    output;/*显式输出。*/
    end;
    run;

    三、宏变量的间接引用(多个&)

    解析规则个人总结为:从左至右,相邻两&变一个&,每轮组合若有落单的&宏变量解析一次。如下列值第一次扫描,左两组合变为1个&,该轮扫描第三个&落单,即解析&day为day1,此时为%put&day1;day1解析为day2。

    再如%put&&&&&&&day;7个&,第一轮解析,左六相邻6个&两两组合变变成三个&&&,落单一个&则解析,结果为%put &&&day1,第二轮为%put &day2,第三轮则为day3。 

    例子:

    %let day=day1;
    %let day1=day2;
    %let day3=day4;
    %put &&&day;

  • 相关阅读:
    多线程的互斥(下)——信号量
    Linux下几种另类创建文件之方法
    Linux下VsFTP和ProFTP用户管理高级技巧 之一
    全面了解Linux下Proc文件系统
    许可证大阅兵
    SSH远程快速登录Linux
    为root账户更名
    Linux集群的I/O性能测试
    Think Pad笔记本分区解决思路及方法
    图形界面备份Linux系统介绍
  • 原文地址:https://www.cnblogs.com/SSSR/p/6908521.html
Copyright © 2020-2023  润新知