前几天一个朋友问我如何快速的在数据集中指定位置插入空白记录。当时我也是愣了一下,以前实现输出制作排版都是在proc report输出时进行设置的,还真没在数据集中的指定位置添加空白行(proc report通过out=也可以实现,感觉又写麻烦)。所以呀,小编就写了一个小程序,来实现数据集中指定位置添加空白行!虽然程序的功能很单一,但是同样小编认为是这也是一个很有趣的程序,所以啊,小编就给大家分享一下下~
在贴代码前,先来看看最原始的需求,最开始需求是这样的,想要在数据集某变量分组后面插入空白行!于是小编就做了一个简易的测试集!
data test1;
do group=1 to 4;
do i=1 to 3;
output;
end;
end;
run;
小编一贯认为不管写大型的程序还是小型的程序,写程序的思路和原理永远是最重要的,只要有思路了,实现起来就非常简单了。小编是这样想的,先排序,然后就利用last.group与output语句来实现添加空白记录!不理解就看代码!
程序已写好,复制即可用~
/*************************************************************************************************************************
宏名称 : addline
目的 : 给数据集添加空白记录
参数说明 :
inds 输入数据集
ouds 输出数据集
keyord 排序分组变量
blanknum 插入空白行数(默认:1)
实例 :; ;
________________________________________________________________________________________________________________________
__________________________________________________________________________________________________________________________
版本 日期 修改人 修改描述
--- ----------- ------------ ----------------------------------------------------------------------------------
1.0 2018.05.11 setup 创建
****************************************************************************************************************************************/
%macro addline(inds=,outds=,keyord=,blanknum=1);
%local libname memname;
%if &inds.= %then %do;
%put NOTE:plesce check your dataset name;
%goto exit;
%end;
%if %length(%sysfunc(compress("&inds.","."))) ne %length(%sysfunc(compress("&inds.",""))) %then %do;
%let libname=%scan("&inds.",1,".");
%let memname=%scan("&inds.",2,".");
%end;
%else %do;
%let libname=WORK;
%let memname=&inds.;
%end;
proc sql noprint;
select distinct NAME into:varlist separated by "," from dictionary.columns where libname=upcase("&libname.") and memname=upcase("&memname.");
quit;
data &outds.;
set &inds.;
sys_ord=_N_;
run;
proc sort data=&outds. out=&outds. sortseq=linguistic(numeric_collation=on);by &keyord. sys_ord;quit;
data &outds.;
set &outds. end=last;
by &keyord. sys_ord;
if ^missing(&keyord.) then output &outds.;
if last.&keyord. and not last then do;
do _snum=1 to &blanknum.;
call missing(&varlist.);
output &outds.;
end;
end;
drop _snum sys_ord;
run;
%exit:
%mend;
宏怎么使用,见代码中的参数说明!下面还是来测试一下宏并看下结果。
%addline(inds=test1,outds=test2,keyord=group,blanknum=2);
这个小程序算是写完了,至于加空白行到底要干嘛,其实不重要!重要的是思路,是语句~不过突然临时起意,突破分组限制,在指定行号后面添加空白行!
/*************************************************************************************************************************
宏名称 : addline2
目的 : 给数据集添加空白记录
参数说明 :
inds 输入数据集
ouds 输出数据集
line 指定行号后面添加空白行
实例:%addline2(inds=test1,outds=test2,line=%str(2 5 8)) ;
________________________________________________________________________________________________________________________
__________________________________________________________________________________________________________________________
版本 日期 修改人 修改描述
--- ----------- ------------ ----------------------------------------------------------------------------------
1.0 2018.05.11 setup 创建
****************************************************************************************************************************************/
%macro addline2(inds=,outds=,line=);
%local libname memname;
%if &inds.= %then %do;
%put NOTE:plesce check your dataset name;
%goto exit;
%end;
%if %length(%sysfunc(compress("&inds.","."))) ne %length(%sysfunc(compress("&inds.",""))) %then %do;
%let libname=%scan("&inds.",1,".");
%let memname=%scan("&inds.",2,".");
%end;
%else %do;
%let libname=WORK;
%let memname=&inds.;
%end;
proc sql noprint;
select distinct NAME into:varlist separated by "," from dictionary.columns where libname=upcase("&libname.") and memname=upcase("&memname.");
quit;
data &outds.;
set &inds.;
output &outds.;
if _N_ IN (&line.) then do;
call missing(&varlist.);
output &outds.;
end;
run;
%exit:
%mend;
也还是看看效果~
%addline2(inds=test1,outds=test2,line=%str(2 5 8));
今天就这么多了,后续内容,敬请期待~