设为首页收藏本站

EPS数据狗论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1551|回复: 0

实现多选值FORMAT的添加

[复制链接]

11

主题

156

金钱

210

积分

入门用户

发表于 2019-7-12 15:41:54 | 显示全部楼层 |阅读模式

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

程序实现效果
先来看看程序实现的效果(如下图),此时定义的是1=张三、2=李四、3=王五。
1.png
将这个程序写成了一个简单的宏,下面来看一下生成上面结果的程序。
  1. %add_multipe_fmt(inds=a,invar=x,dlm=%str(,)
  2. ,valuelist=%str(1=张三|2=李四|3=王五),orderYn=1,fmtname=testfmt4_);
  3. data b2;
  4. set a;
  5. format x $testfmt4_.;
  6. run;
复制代码


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

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

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

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

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

  7. *将数据集衍生一个行号,并根据分隔符拆分数据;
  8. data tmp_ds2;
  9. set tmp_ds1;
  10. line1=_N_;
  11. do i=1 to count(strip(&invar;),"&dlm.;")+1;
  12.    line2=i;
  13.    value_s=kscan(strip(&invar;),i,"&dlm.;");
  14.    if index(value_s,'-') then do;
  15.      do _sm_=input(scan(value_s,1,'-'),??best.) to input(scan(value_s,2,'-'),??best.);
  16.        value_s=strip(vvalue(_sm_));
  17.        output;
  18.      end;
  19.    end;
  20.    else output;
  21. end;
  22. run;

  23. /*针对选项值进行一步处理,将宏变量valuelist 存入数据集中(以“|”作为分隔符)*/
  24. data valuelist;
  25. length valuelist $20000.;
  26. format valuelist $20000.;
  27. informat valuelist $20000.;
  28. valuelist="&valuelist.;";
  29. do i=1 to count(strip(valuelist),"|")+1;
  30.    valuelist_s=kscan(strip(valuelist),i,"|");
  31.    valuelist_s1=kscan(valuelist_s,1,"=");
  32.    valuelist_s2=kscan(valuelist_s,2,"=");
  33.    output;
  34. end;
  35. run;
  36. *将选项值进行一个left join ;
  37. proc sql undo_policy=none;
  38. create table tmp_ds3 as
  39. select  a.*,b.valuelist_s2
  40. from  tmp_ds2  as a
  41. left join  valuelist  as b
  42. on a.value_s =b.valuelist_s1
  43. order by line1,line2;
  44. quit;

  45. *如果排序 orderYn=1 ;
  46. %if &orderYn.; eq 1 %then %do;
  47. proc sort data=tmp_ds3  out=tmp_ds3  sortseq=linguistic(numeric_collation=on);by line1 value_s ;quit;
  48. %end;
  49. data tmp_ds4;
  50. set tmp_ds3;
  51. by line1 ;
  52. length final $20000.;
  53. retain final ;
  54. if first.line1 then do;
  55. final=strip(valuelist_s2);
  56. end;
  57. else do;
  58. final=strip(catx("&dlm.;",final,valuelist_s2));
  59. end;
  60. fmt=quote(strip(&invar.;))||strip("=")||quote(strip(final));
  61. if last.line1 then output;
  62. run;
  63. proc sql noprint;
  64. select fmt into:add_fmt separated by "  " from tmp_ds4   ;
  65. quit;

  66. proc format ;
  67. value $ &fmtname.; &add;_fmt.;
  68. run;
  69. *在日志打印内容;


  70. %put   ********************多选FORMAT:&fmtname.;已生成*********************;
  71. %put  &add;_fmt.;
  72. proc delete data=work.tmp_ds1 work.tmp_ds2 work.tmp_ds3 work.tmp_ds4;run;
  73. %mend;
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

客服中心
关闭
在线时间:
周一~周五
8:30-17:30
QQ群:
653541906
联系电话:
010-85786021-8017
在线咨询
客服中心

意见反馈|网站地图|手机版|小黑屋|EPS数据狗论坛 ( 京ICP备09019565号-3 )   

Powered by BFIT! X3.4

© 2008-2028 BFIT Inc.

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