楼主: bwxiaok
3084 6

想写一个宏函数实现一个简单的功能,求大牛指教! [推广有奖]

  • 0关注
  • 0粉丝

大专生

28%

还不是VIP/贵宾

-

威望
0
论坛币
27 个
通用积分
0.0652
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
378 点
帖子
23
精华
0
在线时间
58 小时
注册时间
2013-6-8
最后登录
2025-10-16

楼主
bwxiaok 发表于 2014-1-21 20:02:51 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
编写一个宏函数mseparate(test,d1 d2 d3...dn):给定一个数据集test,输入数据分层的界限值d1,d2,d3...dn(假设界限值顺序都是d1<d2<d3...dn),自动按照界限值在原数据集生成数据分层标签flag。
例如:
有一个原始数据集test,只有一个字段num:
num
1
330
50
180
1500

1、如果按0,100两个界限值给数据分层,引用函数mseparate(test,0 100),得到新数据集:
num flag
1   【0,100)
330 【100,+)
50  【0,100)
180 【100,+)
1500【100,+)

2、如果增加一个界限值500,则引用函数mseparate(test,0 100 500),得到新数据集:
num flag
1   【0,100)
330 【100,500)
50  【0,100)
180 【100,500)
1500【500,+)

小弟刚接触SAS宏,对宏还不是很熟悉,工作中有大量的数据分层工作,所以想写个宏来实现自动分层的功能,我的思路是先计算界限值的个数n,并且保存在x1,x2,x3..xn中,但是接下来对数据集的处理就各种出错了,弄了很久都没有结果,不知道有哪位SAS大神能帮帮忙实现这个函数?

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:宏函数 separate test Rate Est

沙发
bwxiaok 发表于 2014-1-22 10:12:19
自顶一下~求大神出现啊~

藤椅
yongyitian 发表于 2014-1-22 10:43:13
try this
  1. data a;
  2. input num;
  3. datalines;
  4. 1
  5. 330
  6. 50
  7. 180
  8. 1500
  9. ; run;

  10. %macro mymacro(ds=, level=0 100 300 500);
  11. data &ds;
  12.    length flag $200.;
  13.    level = "&level";      
  14.        n = countw(level, ' ');  
  15.     last = scan(level, n, ' ')*1;   

  16.    set a;
  17.      if num > last then flag = cats('[', compress(last), ',+)');
  18.      if num < last then do;   
  19.        do i = n-1 to 1 by -1;
  20.               if num > scan(level, i)*1 then do;
  21.             flag = cats('[' , scan(level, i), ", ", scan(level, i+1), ' )');
  22.             leave;
  23.             end;
  24.         end;
  25.       end;
  26.   drop last i n level;
  27. run;
  28. %mend mymacro;
  29. %mymacro(ds=aa, level=0 100 300 500);
复制代码

板凳
Jessup007 发表于 2014-1-22 20:41:28
  1. %macro mseparate(ds=,var=,vlist=);
  2. data fmtin;          
  3.    length label $ 200 fmtname start end $ 20 Sexcl Eexcl $ 1;
  4.    retain fmtname "fmt" Sexcl "N" Eexcl "Y";
  5.    %let i=1;
  6.    %do %while(%scan(&vlist.,&i.) ne );
  7.       %if %scan(&vlist.,%eval(&i.+1)) ne %then %do;
  8.              start="%scan(&vlist.,&i.)";
  9.                      end="%scan(&vlist.,%eval(&i.+1))";
  10.                      label=compress(cat("[",start,",",end,")"));
  11.                      output;
  12.           %end;
  13.           %else %do;
  14.              start="%scan(&vlist.,&i.)";
  15.                      end="High";
  16.                      label=compress(cat("[",start,",+)"));
  17.              output;
  18.          %end;
  19.          %let i=%eval(&i.+1);
  20.   %end;
  21. run;
  22. proc format cntlin=fmtin;
  23. run;
  24. data &ds.;
  25.    set &ds.;
  26.    length flag $ 20;
  27.    flag=put(&var.,fmt.);
  28. run;
  29. %mend mseparate;

  30. data test;
  31.    input num@@;
  32. datalines;
  33. 1 330 50 180 1500
  34. ;
  35. run;

  36. %mseparate(ds=test,var=num,vlist=0 100)
  37. proc print data=test noobs;
  38. run;

  39. %mseparate(ds=test,var=num,vlist=0 100 500)
  40. proc print data=test noobs;
  41. run;
复制代码

报纸
bwxiaok 发表于 2014-1-22 21:34:16
yongyitian 发表于 2014-1-22 10:43
try this
看懂了!啊果然简洁易懂,我还想着如何在data步里引用宏而不出错呢~膜拜!

地板
bwxiaok 发表于 2014-1-22 21:36:04
Jessup007 发表于 2014-1-22 20:41
感谢!你的这个同样也实现了!等我慢慢学习一下~

7
ntsean 发表于 2014-1-24 09:44:19
你这种情况,我一般建立一个 format
然后可以用 put函数转换成需要的分组

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2026-1-1 00:46