楼主: heguima
4926 17

【每日一考】怎么编写一个宏,把一个变量的最大5个值和最小五个值列出来? [推广有奖]

11
heguima 发表于 2014-12-30 09:11:40
jl60156 发表于 2014-12-30 00:00
%macro minmax5(dsin=,dsout=,var=, n=5);
proc sort data=&dsin out=temp1(keep=&var rename=(&var=&var. ...
要是变量多的话就不太好用了,比如同时要求X,Y,Z的最大五个和最小五个,那就要运行三次,八楼那位仁兄的思路很不错

12
mingfeng07 学生认证  发表于 2014-12-30 09:11:50
heguima 发表于 2014-12-30 09:07
,小小的建议,可以把过程中的生成的文件删掉,只留最后结果文件
恩,有道理,在循环最后加一个:
  1. proc delete data=a b c;
  2. run;
复制代码

13
heguima 发表于 2014-12-30 10:23:14
mingfeng07 发表于 2014-12-30 09:11
恩,有道理,在循环最后加一个:
有时我们更希望能加上ID值,如图,看看最大最小五个值所对应的ID号。
有如下方法:
data test;
input id$ x y z ;
cards;
201 2 3 1
202 4 8 6
309 4 3 6
205 4 6 8
307 9 3 1
401 11 24 65
504 47 95 21
361 78 4 2
804 6 47 8
631 14 13 47
99 14 18 64
85 111 23 47
;
run;
ods output  ExtremeObs=race_e;
proc univariate data=test  nextrobs=5;
var x y z;
id id;
run;
ods output close;

这种方法同样是变量多不方便,不知仁兄能否改进你的宏添加ID号进去

11.JPG (18.08 KB)

11.JPG

14
mingfeng07 学生认证  发表于 2014-12-30 13:41:34
heguima 发表于 2014-12-30 10:23
有时我们更希望能加上ID值,如图,看看最大最小五个值所对应的ID号。
有如下方法:
data test;
  1. %macro test(lib,data);
  2. proc sql;
  3. create table a as select * from sashelp.vcolumn where libname=upcase("&lib") and memname=upcase("&data");
  4. quit;
  5. proc sql;
  6. select count(name) into:N from a;
  7. select name into:var1-:var%left(&N.) from a;
  8. select count(*) into:N_1 from &data.;
  9. quit;
  10. %do i=2 %to &N.;
  11. data b(keep=&var1 type value);
  12. set &data;
  13. type="&&var&i.";
  14. rename &&var&i.=value;
  15. run;
  16. proc sort data=b;/*选择性是否添加去掉重复变量的nodupkey*/
  17. by value;run;
  18. data c;
  19. set b;
  20. if _n_<=5 or _n_>=&N_1-4;
  21. run;
  22. %if &i.=2 %then %do;
  23. data want;
  24. set c;
  25. run;
  26. %end;
  27. %else %do;
  28. proc append base=want data=c;
  29. run;
  30. %end;
  31. %end;
  32. proc delete data=a b c;
  33. run;
  34. %mend;
  35. %test(work,test);
复制代码
已有 1 人评分学术水平 热心指数 信用等级 收起 理由
heguima + 1 + 1 + 1 精彩帖子

总评分: 学术水平 + 1  热心指数 + 1  信用等级 + 1   查看全部评分

15
823954913 发表于 2014-12-30 14:35:21
  1. %macro highlow(Dsn=, /* 数据集名称 */
  2. Var=, /* 排序变量 */
  3. Idvar=, /* 观测名称变量 */
  4. low_n=, /* 需要抽取多少个最小的观测 */
  5. high_n=/* 需要抽取多少个较大的观测 */);
  6. proc sort data=&Dsn(keep=&Idvar &Var
  7. where=(&Var is not missing)) out=tmp;
  8. by &Var;
  9. run;
  10. data _null_;
  11. set tmp nobs=Num_obs;
  12. call symput('Num',Num_obs);
  13. stop;
  14. run;
  15. %let High1 = %eval(&Num - &high_n + 1);
  16. data &dsn._new;
  17. set tmp(obs=&low_n) tmp(firstobs=&High1);
  18. if _n_<=&low_n then rang="较小的";
  19. else rang="较大的";
  20. run;
  21. proc delete data=tmp;
  22. run;
  23. %mend highlow;

  24. %highlow(Dsn=test, /* Data set name */
  25. Var=x, /* Variable to list */
  26. Idvar=y, /* ID Variable */
  27. low_n=3, /* Number of  lowvalues to list */
  28. high_n=1/* Number of highvalues to list */);
复制代码
已有 1 人评分学术水平 热心指数 信用等级 收起 理由
heguima + 1 + 1 + 1 精彩帖子

总评分: 学术水平 + 1  热心指数 + 1  信用等级 + 1   查看全部评分

16
heguima 发表于 2014-12-31 08:59:26
mingfeng07 发表于 2014-12-30 13:41
还是那样的问题,如果要求的变量有很多(例如几百个),那么就不太方便了,用个循环的话就会好很多

17
heguima 发表于 2014-12-31 08:59:57
823954913 发表于 2014-12-30 14:35
还是那样的问题,如果要求的变量有很多(例如几百个),那么就不太方便了,用个循环的话就会好很多

18
heguima 发表于 2014-12-31 09:01:55
mingfeng07 发表于 2014-12-30 13:41
感谢各位表达自己的思路,【每日一考】为大家提供SAS在运用中遇到的问题,在解决问题的同时共同学习

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

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