SAS编程-宏:查询数据会合全部空变量

程序员 2024-9-30 20:53:28 17 0 来自 中国
之前写过[b]查询数据会合的空变量[/b]的宏步调,一时没找到。于是重写一版,并以此简朴先容下宏步调的构建过程。
这篇文章从功能算法讲起,然后编程实现算法逻辑,末了举行宏步调的构建,宏步调完备代码在文章第4部分汇总。
希望这篇文章可以对读者一样寻常SAS编程工作有所资助。
先展示宏步调输出的结果:
[b]更多临床试验SAS编程内容,接待关注:SAS茶谈。[/b]
[size=5]1. 步调算法操持[/size]

[b]宏步调的构思操持,从最小功能单位开始[/b]。对于查询数据会合的空变量,我们从单个数据集的单个变量的判断做起。
演示数据集使用SASHELP.Class,举行新增空变量处置惩罚。
***test dataset;data class;  set sashelp.class;  a = "";  b = .;run;现在数据会合有两个完全为空的变量,宏步调的目的就是把这两个变量找出来。[b]用什么步调语言来表示空变量,这个须要步调员本身探索和实验[/b]。我选用的是,变量不为空的记载数为0。听起来有些拗口,但步调实现起来比力简朴。
[size=5]2. 编程实现算法[/size]

Proc SQL和Data步都可以或许实现非空记载数的统计,但由于SQL的聚合函数跨记载处置惩罚相对方便,我以SQL语句举行演示,先统计变量Name不为空的记载数:
***Get number of non-missing records;proc sql noprint;  create table result1 as    select "CLASS" as Dataset length=50, "NAME" as Var length=50, sum(not missing(name)) as Sum    from class;quit; 5.png 依次类推,我们可以统计出每个变量不为空的记载数,然后依次将各个结果纵向拼接在一起。
SQL中纵向拼接的查询表达是outer union,默认是按两个查询表依次位置拼接的,相同变量拼接需加上关键字corresponding/corr,语法细节参考SAS官方文档:SAS Help Center: query Expression。
***Get number of non-missing records for all variables;proc sql noprint;  create table result1 as    select "CLASS" as Dataset length=50, "NAME" as Var length=50, sum(not missing(NAME)) as Sum    from class    outer union corr    select "CLASS" as Dataset length=50, "SEX" as Var length=50, sum(not missing(SEX)) as Sum    from class    outer union corr    select "CLASS" as Dataset length=50, "AGE" as Var length=50, sum(not missing(AGE)) as Sum    from class    outer union corr    select "CLASS" as Dataset length=50, "HEIGHT" as Var length=50, sum(not missing(HEIGHT)) as Sum    from class    outer union corr    select "CLASS" as Dataset length=50, "WEIGHT" as Var length=50, sum(not missing(WEIGHT)) as Sum    from class    outer union corr    select "CLASS" as Dataset length=50, "A" as Var length=50, sum(not missing(A)) as Sum    from class    outer union corr    select "CLASS" as Dataset length=50, "B" as Var length=50, sum(not missing(B)) as Sum    from class;quit; 6.png 再获取数据会合全部变量不为空的记载数后,我们只须要筛选记载数为0的记载就可以获取空变量的信息。为展示方便,我们可以把两个变量信息综合在一起,这个可以通过转置后横向拼接实现。
***Display result;proc transpose data = result1 out=result2  prefix=emp_;  by dataset;  var Var;  where sum = 0;run;data result3;  set result2;  length Empvar $2000;  Empvar = catx(", ", of emp_;  keep dataset empvar;run; 7.png 如许处置惩罚看起来比力轻便,也方便后续多数据集查抄空变量结果的拼接。
关于步调,多解释一点,SAS中函数批量处置惩罚变量序列时,须要在变量序列前添加of。假如不批量处置惩罚,也可以手动输入每一变量名称,比方:
empvar = catx(", ", emp_1, emp_2);假如不知道输出变量的数量,使用特定的前缀对变量举行标记,再用函数批量处置惩罚,这个过程会变得轻便很多。
[size=5]3. 宏步调的构建[/size]

在手动编程将算法实现后,就可以动手构建宏步调。就我个人SAS编程履历来讲,宏步调的作用重要有两个:
[indent]
[list]
[*]单个功能的重复调用;
[*]宏循环的批量处置惩罚。
[/list][/indent]关于这两个作用,读者可以与本身的宏步调编程履历对照明确,这里就不外多睁开。
从以上手动编程的过程中可以看出,步调重要“重复”的地方在于各个变量不为空记载的统计。除了变量名称,拼接步调完全相同。假如我们将须要处置惩罚的变量名称生存到宏变量序列中,就可以通过宏循环依次举行调用,并通过宏循环批量构建步调。
[size=4]3.1 生成宏变量(序列)[/size]

宏循环处置惩罚的关键,在于循环次数的获取以及变量名称宏变量序列。
宏变量的生成常用有2种方法:
[indent][list=1]
[*]Proc SQL 中的into :语句
[*]Data步中的call symputx语句
[/list][/indent]SAS数据集的元数据信息生存在SAS字典中,这里我以Data步中的call symputx语句举行举例。
变量数量生存到宏变量中:
***Get the number of vairiables;data tmp1;  set sashelp.vtable;  where libname = "WORK" and memname = "CLASS";  call symputx("nvar", strip(put(nvar,best.)));run;%put nvar= &nvar.;变量名称生存到宏变量序列中:
***Get variables' name;data tmp2;  set sashelp.vcolumn;  where libname = "WORK" and memname = "CLASS";  call symputx("var"||strip(put(varnum, best.)), strip(name));run;%put var1= &var1.;%put var7= &var7.;这里一些读者大概有如许的想法:这里完全可以使用一个Data步,从SASHELP.vcolumn数据集获取末了一条数据的varnum作为宏变量nvar的取值。雷同如许的处置惩罚:
***Get variables' name and nvar;data tmp3;  set sashelp.vcolumn end=eof;  where libname = "WORK" and memname = "CLASS";  call symputx("var"||strip(put(varnum, best.)), strip(name));  if eof then call symputx("nvar1", strip(put(varnum, best.)));  %put nvar1= &nvar1.;run;以当前演示数据集来看,这两种方式处置惩罚结果相同。但假如一个数据会合没有任何变量,这时间SASHELP.vcolumn中是没有记载的,而SASHELP.vtable中是有nvar=0的记载。此时后者无法抓取数据集的变量数。
假如感爱好,读者可以用以下空数据集举行测试:
data test;run;[size=4]3.2 宏循环的实现[/size]

宏循环须要在宏步调中举行,宏步调的构建尽大概包罗大概的情况。这里根据变量数量举行分类处置惩罚。
***Temp macro;%macro check_empty_var;  %if &nvar. = 0 %then %do;  data result;    length Dataset $50 empvar $2000;    dataset = "CLASS";    empvar = "There is no variable in the dataset Class!";  run;%end;%else %if &nvar. > 0 %then %do;  %if &nvar. = 1 %then %do;    proc sql noprint;       create table result1 as         select "CLASS" as domain length=50, "&var1." as Var length=50, sum(not missing(&var1.)) as Sum         from class      ;    quit;  %end;  %if &nvar. > 1 %then %do;    proc sql noprint;       create table result1 as         select "CLASS" as Dataset length=50, "&var1." as Var length=50, sum(not missing(&var1.)) as Sum         from class    %do i = 2 %to &nvar.;      outer union corr      select "CLASS" as Dataset length=50, "&&var&i." as Var length=50, sum(not missing(&&var&i.)) as Sum        from class    %end;      ;    quit;  %end;  *Display result;  proc transpose data = result1 out=result2 prefix=emp_;    by dataset;    var Var;    where sum = 0;   run;    data result;    set result2;        length Empvar $2000;    Empvar = catx(", ", of emp_;    keep dataset empvar;  run;   %end;%mend check_empty_var;%check_empty_var;以上宏步调运行结果如下,与手动编程结果保持划一。
[size=4]3.3 宏参数的设置[/size]

宏参数一般有3类:
[indent][list=1]
[*]输入内容(变量/数据集)
[*]输出内容(变量/数据集)
[*]特定条件
[/list][/indent]这个宏步调从简,直接以Reslt数据集输出,不须要额外的筛选条件,只需设置输入数据集就好。为了省事,也不在宏里判断输入数据集的逻辑库名称、数据集名称,直接界说到宏参数中。
%macro check_empty_var(libname=WORK, memname=);...%mend check_empty_var;确定宏参数后,须要在之前开端宏步调中举行内容更换,如许方便以后对差异参数对象的处置惩罚调用。
[size=5]4. 宏步调代码汇总[/size]

完备宏步调需综合以上内容,并尽大概思量多种大概环境,以求宏步调运行稳固。比方,输入数据集不存在的环境;数据集没有空变量的环境。
假如输入数据集不存在,最好能在Log中输出一条Warning记载作为提示。为制止一些步调文本查抄机制的误判,War ning最好能拆开处置惩罚下。
其他处置惩罚细节就不再睁开形貌,汇总步调如下:
%macro  check_empty_var(libname=WORK, memname=);  ***Dataset exists;%if %sysfunc(exist(&libname..&memname.)) = 1 %then %do;***Get the number of vairiables;data _null_;  set sashelp.vtable;  where libname = upcase("&libname.") and memname = upcase("&memname.");  call symputx("nvar", strip(put(nvar, best.)));run;%put nvar= &nvar.;***Macro loop;%if &nvar. = 0 %then %do;  data result;    length Dataset $50 Empvar $2000;    dataset = upcase("&libname..&memname.");    Empvar= "There is no variable in the dataset %sysfunc(upcase(&libname..&memname.)).";  run;%end;%else %if &nvar. > 0 %then %do;**Get variables name;data _null_;  set sashelp.vcolumn;  where libname = upcase("&libname.") and memname = upcase("&memname.");  call symputx("var"||strip(put(varnum, best.)), strip(name));run;%put var1= &var1.;  %if &nvar. = 1 %then %do;    proc sql noprint;       create table result1 as         select upcase("&libname..&memname.") as Dataset length=50, "&var1." as Var length=50, sum(not missing(&var1.)) as Sum         from &libname..&memname.      ;    quit;  %end;  %if &nvar. > 1 %then %do;    proc sql noprint;       create table result1 as         select upcase("&libname..&memname.") as Dataset length=50, "&var1." as Var length=50, sum(not missing(&var1.)) as Sum         from &libname..&memname.    %do i = 2 %to &nvar.;      outer union corr      select upcase("&libname..&memname.") as Dataset length=50, "&&var&i." as Var length=50, sum(not missing(&&var&i.)) as Sum        from &libname..&memname.    %end;      ;    quit;  %end;  *Display result;  proc transpose data = result1 out=result2 prefix=emp_;    by dataset;    var Var;    where sum = 0;   run;    data result;    set result2;        length emp_1 $50 Empvar$2000;    if not missing(emp_1) then empvar = catx(", ", of emp_;    else do;      dataset = upcase("&libname..&memname.");      empvar = "There is no empty variable in the dataset %sysfunc(upcase(&libname..&memname.)).";    end;    keep dataset empvar;  run;   %end;%end;***Dataset does not exist;%if %sysfunc(exist(&libname..&memname.)) ne 1 %then %do;  %put %sysfunc(compress(War ning)): Dataset %sysfunc(upcase(&libname..&memname.)) does not exist. ;%end;%mend check_empty_var;%check_empty_var(libname=work, memname=class);%check_empty_var(libname=work, memname=Yeteng);假如数据集不存在,末了显示结果如下:
[size=5]5. 总结[/size]

文章梳理了查询数据会合全部空变量宏步调构建过程,希望可以或许对读者有所资助。[b]单个数据集处置惩罚的完成,也方便后续对多个数据集批量处置惩罚[/b]。
[b]感谢阅读, 接待关注:SAS茶谈!
如有疑问,接待批评交换![/b]
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-10-18 14:22, Processed in 0.190623 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表