追逐夢想的孩子 发表于 2019-7-24 13:22:12

SAS-如何实现多选值格式的添加


在处理数据时,有时候会遇见变量值为多选的情况,此时如果要给变量添加上的格式,就略微麻烦许多。分享一段针对此种情况自动生成格式的程序。

程序实现效果:
先来看看程序实现的效果(如下图),此时定义的是1 =张三,2 =李四,3 =王五。


下面来看一下生成上面结果的程序。
%add_multipe_fmt(inds=a,invar=x,dlm=%str(,)
,valuelist=%str(1=张三|2=李四|3=王五),orderYn=1,fmtname=testfmt4_);
data b2;
set a;
format x $testfmt4_.;
run;


程序原理
在分享这个程序的原理前,先来看看设置的那些宏参数以及其作用。



原理:
1.获取变量观测值的种类(去重)
2.根据指定分割符将观测中的值进行拆分(得到一个数据集)
3.根据输入的值列表生成一个存放单选值及对应格式的数据集
4.将上面俩个数据集进行left join,在进一步组合等操作
5.利用proc格式语句生成格式


程序:
%macro add_multipe_fmt(inds=,invar=,dlm=%str(),valuelist=,orderYn=1,fmtname=);

*获取数据集中观测种类;

proc sql undo_policy=none;
create table tmp_ds1 as
select distinct &invar. from&inds.;
quit;

*将数据集衍生一个行号,并根据分隔符拆分数据;
data tmp_ds2;
set tmp_ds1;
line1=_N_;
do i=1 to count(strip(&invar),"&dlm.")+1;
   line2=i;
   value_s=kscan(strip(&invar),i,"&dlm.");
   if index(value_s,'-') then do;
   do _sm_=input(scan(value_s,1,'-'),??best.) to input(scan(value_s,2,'-'),??best.);
       value_s=strip(vvalue(_sm_));
       output;
   end;
   end;
   else output;
end;
run;

/*针对选项值进行一步处理,将宏变量valuelist 存入数据集中(以“|”作为分隔符)*/
data valuelist;
length valuelist $20000.;
format valuelist $20000.;
informat valuelist $20000.;
valuelist="&valuelist.";
do i=1 to count(strip(valuelist),"|")+1;
   valuelist_s=kscan(strip(valuelist),i,"|");
   valuelist_s1=kscan(valuelist_s,1,"=");
   valuelist_s2=kscan(valuelist_s,2,"=");
   output;
end;
run;
*将选项值进行一个left join ;
proc sql undo_policy=none;
create table tmp_ds3 as
selecta.*,b.valuelist_s2
fromtmp_ds2as a
left joinvaluelistas b
on a.value_s =b.valuelist_s1
order by line1,line2;
quit;

*如果排序 orderYn=1 ;
%if &orderYn. eq 1 %then %do;
proc sort data=tmp_ds3out=tmp_ds3sortseq=linguistic(numeric_collation=on);by line1 value_s ;quit;
%end;
data tmp_ds4;
set tmp_ds3;
by line1 ;
length final $20000.;
retain final ;
if first.line1 then do;
final=strip(valuelist_s2);
end;
else do;
final=strip(catx("&dlm.",final,valuelist_s2));
end;
fmt=quote(strip(&invar.))||strip("=")||quote(strip(final));
if last.line1 then output;
run;
proc sql noprint;
select fmt into:add_fmt separated by "" from tmp_ds4   ;
quit;

proc format ;
value $ &fmtname. &add_fmt.;
run;
*在日志打印内容;


%put   ********************多选FORMAT:&fmtname.已生成*********************;
%put&add_fmt.;
proc delete data=work.tmp_ds1 work.tmp_ds2 work.tmp_ds3 work.tmp_ds4;run;
%mend;
页: [1]
查看完整版本: SAS-如何实现多选值格式的添加