#SAS进阶-SAS宏实例解析

本文介绍了SAS宏的几个实例,包括使用宏变量进行异常值检查,批量合并数据集,统计单个变量和所有变量的分布。通过这些例子,详细讲解了宏的使用方法和常见操作,帮助读者深入理解SAS宏的运用。

好了,这周算是有些时间来更新一下咯~按照之前的约定,今天我就写一下sas宏的一些例子的解析,例子均为在学习中遇到的作业习题,是自己在初步学习sas宏之后写出来的,可能写得并不是最优的解法,若有,希望大家可以和我提出来呀嘻嘻~

0?wx_fmt=jpeg

话不多说,马上开始今天的sas宏的例子解析,今天我准备了一些例子,顺序也是按照难度来排的,会介绍一下宏的基本用法以及一些常见的错误,希望可以帮助到大家学习~


好了,之前有同学问我的sas代码颜色有什么含义,那我今天就统一解释一下。

/*这种颜色*/ :一般为注释,就是对这一行代码进行解释性说明,不会算入代码运行中;

proc:这种颜色一般为语法主体部分,一般出现在代码开头以及结尾;

output:这种颜色一般为语法中的关键字;

q1_age:这种就是普通代码了,没有什么特别含义,但也是最重要的东西。



例1:使用宏变量,对user表的age进行异常值检查,以1.5倍iqr作为异常值界限,  将含有异常值的记录以SAS数据集单独存储。


proc univariate data=hw1.Q3 noprint;/*proc univariate是sas中用于输出统计量的proc步常用过程*/

    var age; /*设置你要统计的变量*/

    output out=hw1.range_age /*设置输出数据集*/

    q1=q1_age /*统计上界*/

    q3=q3_age /*统计下界*/

    QRANGE=iqr_age; /*统计iqr,即q3-q1的值*/

run;


/*使用data步定义宏,对q1,q3,iqr进行初始化*/

data _null_;

    set hw1.range_age;

    call symput('q3',q3_age);

    call symput('q1',q1_age);

    call symput('iqr',iqr_age);

run;


/*引用宏变量,并将输出结果输出到新数据集q41中*/

data hw1.q41;

    set hw1.q3;

    if age<&q1-1.5*&iqr|age>&q3+1.5*&iqr

    then output;

run;



例2:使用宏来完成读取同一个文件夹下的所有数据集文件,并合并到同一张表(假设所有数据集的字段相同)


libname q4 'F:\指定文件夹地址';

%macro t; /*宏函数的开头*/

  proc contents data=q4._all_ out=cnt(keep=memname) noprint nodetails; run; /*将q4文件夹里的所有数据集进行contents的输出,可以得到所有的数据集名称(memname)*/

  proc sort data=cnt out=q4.cnt nodupkey;by MEMNAME;run;

  proc sql;

    select count(MEMNAME) into:maxobs

    from q4.cnt; /*统计共有多少个数据集,用于后期循环最大次数的指定*/

  quit;

  data _null_;

  set q4.cnt;

%do i=1 %to &maxobs;  /*循环n次,n为数据集的数量*/

  data _null_;

    set q4.cnt(obs=&i firstobs=&i); /*读取第i条记录的观测值*/

    call symputx("MEMNAME",MEMNAME); /*将读取到的观测值赋值给宏变量*/

  run;

  proc append base=q4.r data=q4.&MEMNAME.;run; /*使用append过程进行每次输出结果数据集的拼接*/

%end;

%mend; /*宏函数的结尾*/


%t; /*引用宏函数*/



例3:给定任意表,统计表内任意单个变量的分布,若变量为数值型变量,分布结果包含: 均值 , 标准差,众数, 缺失数,观测数, 0% 25% 50% 75% 100%分位数值,若为字符型变量,分布结果包含:变量值, 频数, 占比。


/*定义数值型处理的宏函数*/

%macro one_n(data=,var=,out=);

    PROC UNIVARIATE data=&data;

        VAR &var;

        OUTPUT OUT=&out

        mean=mean

        STD=std

        NMISS=NMISS

        NOBS=NOBS

        MODE=MODE

        pctlpre=p pctlpts=(0 25 50 75 100);

    run;

%mend one_n;


/*定义字符型处理的宏函数*/

%macro one_c(data=,var=,out=);

    proc freq data=&data;

        tables &var/out=&out;

    run;

%mend one_c;


/*定义主函数,通过判断类型执行不同宏函数*/

%macro one(data=,var=,out=); /*指定宏函数的输入变量*/

    proc contents data=&data out=cnt(keep=name type);run; /*对输入的变量data进行contents计算,得到这个数据集所有变量的数据类型type*/

    proc sql;

        select TYPE into:type1 from cnt

        where NAME=propcase("&var"); /*将你要统计的变量var的数据类型赋值给type1*/

    quit;

    /*对type1进行类型判断,1为数值型,2为字符型,调用不同过程*/

    %if &type1 = 1 %then 

    %do;

      %one_n(data=&data,var=&var,out=&out); /*数值型变量的计算过程,也为宏,这里是直接引用宏的了,而这个宏的定义则在前面就已经定义的了*/

    %end;

    %else 

    %do;

      %one_c(data=&data,var=&var,out=&out); /*字符型变量的计算过程,也为宏,这里是直接引用宏的了,而这个宏的定义则在前面就已经定义的了*/

    %end;

%mend;


/*调用宏函数*/

%one(data=sashelp.class,var=name,out=a);



例4:给定任意表,统计表内所有变量的分布,按变量类型保存到任意指定的两张结果表,若变量为数值型变量,分布结果包含: 均值 , 标准差,众数, 缺失数,观测数, 0% 25% 50% 75% 100%分位数值,若为字符型变量,分布结果包含:变量值, 频数, 占比。

嘿嘿,这道题目其实是上一道题的进阶版,很有意思~


libname a 'C:\Users\Sam-Win\Desktop\SAS学习';

/*定义数值型处理的宏函数*/

%macro two_n(data=,var=,numout=,i=);

    PROC UNIVARIATE data=&data noprint;

        VAR &var.;

        OUTPUT OUT=&&numout.&i. 

        mean=mean

        STD=std

        NMISS=NMISS

        NOBS=NOBS

        MODE=MODE

        pctlpre=p pctlpts=(0 25 50 75 100);

    run;

    data &&numout.&i.;

        set &&numout.&i.;

        length name $10. ;

        name="&var.";

        label mean=mean;

        label std = std;

        label nmiss=missing;

        label nobs=record;

        label mode=mode;

        label p0=p_0;

        label p25=p_25;

        label p50=p_50;

        label p75=p_75;

        label p100=p_100;

    run;

    proc append base=&numout. data=&&numout.&i force;run; /*将输出的结果集用append进行拼接,force关键字可以允许变量数量不同的情况下进行拼接/

%mend two_n;


/*定义字符型处理的宏函数*/

%macro two_c(data=,var=,charout=,i=);

    proc freq data=&data noprint;

        tables &var/out=&&charout.&i.;

    run;

    data &&charout.&i.;

        set &&charout.&i.;

        length varname $10. ;

        varname="&var.";

        rename &var=value;

        label &var=value;

        label COUNT = COUNT;

        label PERCENT=PERCENT;

    run;

    proc append base=&charout. data=&&charout.&i. force;run;

%mend two_c;


/*定义主函数,通过判断类型执行不同宏函数*/

%macro two(data= ,numout=,charout=);

    proc contents data=&data out=cnt(keep=name type);run;

    proc sql;

        select count(name) into:maxobs /*统计共有多少个变量,用于后期循环最大次数的指定,和例2有点像*/

        from cnt;

    quit;

    data _null_;

        set &data;

        %do i=1 %to &maxobs;  /*逐行读取观测,读取不同的变量,并将读取的观测值赋值给宏变量,用于后期的调用*/

            data _null_;

            set work.cnt(obs=&i firstobs=&i);

            call symputx("varname",name);

            call symputx("vartype",type);

        run;

    %if &vartype = 1 %then 

    %do;

      %two_n(data=&data,var=&varname,numout=&numout,i=&i); /*相比上一道题,多了一个i变量*/

    %end;

    %else 

    %do;

      %two_c(data=&data,var=&varname,charout=&charout,i=&i);

    %end;

    %end;

%mend;


/*调用宏函数*/

%two(data=sashelp.class,numout=a,charout=b);


0?wx_fmt=png

好啦,今天就先讲这么多啦,下次计划讲一些sas的统计分析和时间序列模型的预测,主要还是一些描述性统计分析,参数估计与假设检验,方差分析,主成分分析与因子分析,聚类分析,判别分析,回归分析,logistic分析,时间序列分析等等啦,敬请期待!



欢迎关注,嘻嘻~

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值