楼主: dahufa123
1878 0

[SAS] 一个双录入比对程序 [推广有奖]

  • 0关注
  • 2粉丝

本科生

36%

还不是VIP/贵宾

-

威望
0
论坛币
35 个
通用积分
0.2605
学术水平
23 点
热心指数
25 点
信用等级
22 点
经验
3723 点
帖子
66
精华
0
在线时间
62 小时
注册时间
2009-3-16
最后登录
2024-4-8

楼主
dahufa123 发表于 2015-3-9 17:04:33 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

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

经管之家联合CDA

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

感谢您参与论坛问题回答

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

+2 论坛币
研究生时候写的一个问卷双录入比对程序。程序最开始的说明部分有点罗嗦与模糊请谅解。希望各位网友大能不吝赐教。
  1. /*功能:完成两数据集排序、找共同记录、比较等功能,并可将结果存入指定的文件中,
  2. 测试系统:win7
  3. 测试版本:sas9.2
  4. 编写人员:dahufa
  5. 测试人员:dahufa
  6. 联系方式:dahufa123@126.com
  7. 权益保护:可以使用不得传播。如有发现问题或有改动联系作者。
  8. */

  9. /*
  10. 宏参数有以下几个:
  11. base:基础数据集;
  12. compare:比较的数据集;
  13. id:两个数据集比较的依据变量,需两组中变量相同
  14. drop:量比较数据集中不用进行比较的变量,存在多个时彼此间用空格隔开;
  15. transpose:是否转置,即比较的结果是否以每条记录的方式显示,取值范围为0,1。如为0不转置,以变量方式显示;如为1转置,以变量方式显示。默认为不转置;
  16. path:比较差异结果输出的全路径,包括盘号:\文件夹\文件名.后缀名。可以省略,省略及不输出。

  17. 必须定义的变量为base、compare,此时默认比较依据变量为id,不转置,不输出,不去变量。
  18. */

  19. /*
  20. 运行前work中与该程序中间产生的数据集同名的文件需保存。如:
  21.   a、cs、f、s fir1,fir2、fns、sec1、sec2、snf及可能产生的f1、f2、f3……和s1、s2、s3……等。

  22. 判读结果时可能用到的数据集:
  23. fir2:base数据集中id号重复的记录;
  24. sec2:compare数据集中id号重复的记录;
  25. fns:在base数据集中存在而在compare数据集中不存在的变量;
  26. snf:在compare数据集中存在而在base数据集中不存在的变量;
  27. 在校对前需尽可能保证fns与snf中不存在记录,尽可能发现fir2中sec2中id与fir1、sec1相同却不是指一问卷的记录。

  28. 其余数据集的含义:
  29. fir1、sec1:base、compare数据集中id第一次出现的记录;
  30. f、s: base、compare数据集中最后进入比较的记录;
  31. */

  32. /*
  33. 另及小提示:        

  34. 在比较前可以对数据进行一些整理,建议在保留原始记录的基础上用程序进行
  35. 上述的改动(即都通过程序改动数据,而不直接改动数据集),使用更改后的数据集进行比较,而在校对时在原始记录上改错误,
  36. 这样如要得到最后的结果跑一遍改动的程序即可。
  37. */
  38. %macro compare (base=,compare=,id=id,drop= ,transpose=0,path= );
  39. %put &base &compare;
  40. %symdel nw nobs eob;
  41. /*清除本宏中可能出现的全局宏变量,以防止干扰。运行时就此处出现绿字提示“WARNING: 删除宏变量 NW 失败,未找到该变量。
  42. ”等乃正常现象,说明系统中没有此宏变量。*/

  43.   %if  &transpose=1  %then %let transpose=transpose;
  44.   %else %let transpose=;
  45.   /*程序开始*/
  46. proc sort data=&base;
  47. by &id;
  48. proc sort data=&compare;
  49. by &id;
  50. run;

  51. data fir1 fir2;
  52. set &base;
  53.   if first.&id then output fir1;
  54.    else output fir2;
  55. by &id;
  56. run;

  57. data sec1 sec2;
  58. set &compare;
  59.   if first.&id then output sec1;
  60.    else output sec2;
  61. by &id;
  62. run;
  63. data s fns snf;
  64. merge fir1(in=ok1) sec1(in=ok2);
  65.   by &id;
  66.    if ok1=1 and ok2=1 then output s;
  67.    if ok1=1 and ok2=0 then output fns;
  68.    if ok1=0 and ok2=1 then output snf;
  69. run;
  70. data f;
  71. merge sec1(in=ok1) fir1(in=ok2);
  72.   by &id;
  73.    if ok1=1 and ok2=1 then output f;
  74. run;
  75. /*这一段准备数据库,除含宏变量外与普通宏程序完全相同*/

  76. data _null_;
  77. if nobs=0 then do;        
  78.   call symput('nobs',"0"); /*空集非得如此,非空可直接:data _null_;set f nobs=nobs;call symput('obc',nobs);run;*/
  79. end;
  80. else call symput('nobs',put(nobs,best12.));
  81. stop;
  82. set f nobs=nobs;
  83. run;
  84. %put 两数据集间都存在的id唯一的记录有 &nobs 条;
  85. /*以上定f是否是空集, &nobs=0为空集。*/

  86. %if &nobs=0 %then %do;
  87. %window both color=yellow
  88.            #5 @28 '两个数据集之间没有共同记录!' attr=highlight
  89.               color=red
  90.                         #8 @32 '请敲击ENTER键继续' attr=highlight
  91.               color=blue;
  92. %display both delete;
  93. %end;
  94. /*空集直接终止程序,弹出窗口,由用户交互后推出程序。非空执行下面程序*/

  95. %else %do;

  96. ods output comparesummary=cs;
  97. options nodate source    linesize=100 pagesize=30000;
  98.   proc compare data=f  (drop=&drop )
  99.    compare=s (drop=&drop )
  100.     maxprint=(10000 32767) nodate  &transpose;
  101.      id &id;
  102.   run;
  103. ods output close;
  104. dm 'clear output';
  105. /*初步比较了解不等值总数*/

  106. data _null_;
  107. set cs;        
  108.   where batch contains "部分比较变量不等的观测数";
  109.     call symput('eob',compress(batch,,'kd'));
  110. run;
  111. %put 部分比较变量不等的观测数 &eob;
  112. /*看部分比较变量不等的观测数,如eob为0表完全相等*/

  113. %if &eob=0 %then %do;
  114. %window results color=white
  115.            #5 @28 '恭喜你,现在没有发现两遍之间存在差别!' attr=highlight
  116.               color=red
  117.                         #8 @40 '请敲击ENTER键继续' attr=highlight
  118.               color=blue;
  119. %display results delete;
  120. %end;
  121. /*完全相等退出程序*/

  122. %else %do;
  123. data _null_;
  124. set cs;        
  125.   where batch contains "比较不等值总数";
  126.     call symput('nw',compress(batch,,'kd'));
  127. run;
  128. %put 比较不等值总数为 &nw;
  129. /*找不等值总数*/

  130. %if &path^= %then %do;
  131.   proc printto print="&path" new;quit;
  132. %end;
  133. /*从现在开始如Path为非空,则将结果存入path文件*/

  134. %let n=%sysevalf(&nw/32767);
  135. %put 比结果将会是sas容许打印的 &n 倍;
  136. %if &n<1 %then %do;
  137.   options nodate source    linesize=100 pagesize=30000;
  138.    proc compare data=f  (drop=&drop )
  139.     compare=s (drop=&drop )
  140.          maxprint=(10000 32767) nodate  &transpose;
  141.           id &id;
  142.           title "比较数据集&base. 和&compare. 的结果";
  143.   run;        
  144.    proc datasets lib=work nolist;
  145.     delete cs;
  146.    quit;
  147. %end;
  148. /*如果sas能一次打印完全则直接打印(sas最多打印32767行),不然分段打印*/

  149. %else %do;
  150.   %do i=1 %to %eval(&n+1);
  151.      data f&i;
  152.        %if &i=%eval(&n+1) %then %do;
  153.          set f(firstobs=%sysevalf(&nobs*(&i-1)/(&n+1)+1,int) obs=max);
  154.                %end;
  155.        %else %do;
  156.          set f(firstobs=%sysevalf(&nobs*(&i-1)/(&n+1)+1,int) obs=%sysevalf(&nobs*&i/(&n+1),int));
  157.         %end;
  158.      run;

  159.      data s&i;
  160.        %if &i=%eval(&n+1) %then %do;
  161.          set s(firstobs=%sysevalf(&nobs*(&i-1)/(&n+1)+1,int) obs=max);
  162.                    %end;
  163.              %else %do;
  164.          set s(firstobs=%sysevalf(&nobs*(&i-1)/(&n+1)+1,int) obs=%sysevalf(&nobs*&i/(&n+1),int));
  165.               %end;
  166.      run;
  167.         /*将数据分段,分段后逐段比较并将结果输出以保证sas将所有错误一次打印完全*/

  168.    options nodate source    linesize=100 pagesize=30000;
  169.     proc compare data=f&i  (drop=&drop )
  170.      compare=s&i (drop=&drop )
  171.        maxprint=(10000 32767) nodate nosummary &transpose;
  172.      id &id;
  173.           title "比较数据集 &base. 和 &compare. 的结果part&i";
  174.    run;

  175.    proc datasets lib=work nolist;
  176.     delete a cs f1-f%eval(&n+1) s1-s%eval(&n+1);
  177.    quit;
  178.    /*删除中间的数据库*/
  179.   %end;
  180. %end;

  181. %if &path^= %then %do;
  182. Proc printto;quit;         /*将结果输出*/
  183. %end;
  184. %end;
  185. %end;
  186. %mend compare;

  187. /*
  188. 调用示例:
  189. 1.启动sas后第一次调用时先将本文件打开,全选并运行,然后在新建的增强型程序编辑器中写入语句:
  190.   “
  191.   %compare(base=h.firfir,compare=h.secsec,id=id,transpose=0,drop=writer freq,path=g:\sas 比较.txt) ;
  192.   ”
  193.   上例是所有宏参数都指定的情况,宏参数指定最少的情况如下:
  194.   “
  195.   %compare(base=h.firfir,compare=h.secsec) ;
  196.   ”
  197.   第二次及以后要调用该宏仅需运行上述语句即可。

  198. 2.找到本文件存放的路劲如:“d:\sas\compare.sas”,然后在sas程序编辑器中写入:
  199.   “
  200.   %include "d:\sas\compare.sas"        ;
  201.   options mfile mprint MLOGICNEST; *此句及下句允许sas在log窗口中显示宏处理后的程序;
  202.   filename mprint 'f:\a.sas' ;
  203.   %compare(base=h.firfir,compare=h.secsec) ;
  204.   ”
  205.   运行即可。

  206. 建议选第二种,这样可以保证sas程序不会被随便改动。
  207. */



  208. /*另:
  209. base中的id变量与compare中不同的情况下,最好先改相同再比.
  210. */



  211. /*
  212. 2011.7.13追加更正:
  213. 1.两数据库间没有共同id记录的情况;
  214. 2.两数据库间没有找到差别的情况;
  215. 3.改进了寻找不同值数目的方法。
  216. */
复制代码
      其实真正要实现这一比较工作很多其他的工具可以办到,但打印出异同点的就少了许多。再次sas实现该操作也简单,不过sort、merge、compare几个步骤而已,这里面其实是多了个最后的判断罢了。其实没有任何用处,纯粹个人意淫。悲催。

二维码

扫码加我 拉你入群

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

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

关键词:比对程序 双录入 Transpose highlight compress 程序 录入 双录入 比对程序 sas merge compare

已有 1 人评分经验 论坛币 学术水平 热心指数 信用等级 收起 理由
niuniuyiwan + 60 + 60 + 5 + 5 + 5 精彩帖子

总评分: 经验 + 60  论坛币 + 60  学术水平 + 5  热心指数 + 5  信用等级 + 5   查看全部评分

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

本版微信群
加好友,备注jltj
拉您入交流群
GMT+8, 2025-12-5 17:13