- 阅读权限
- 255
- 威望
- 0 级
- 论坛币
- 35 个
- 通用积分
- 0.1405
- 学术水平
- 23 点
- 热心指数
- 25 点
- 信用等级
- 22 点
- 经验
- 3723 点
- 帖子
- 66
- 精华
- 0
- 在线时间
- 62 小时
- 注册时间
- 2009-3-16
- 最后登录
- 2024-4-8
本科生
还不是VIP/贵宾
- 威望
- 0 级
- 论坛币
- 35 个
- 通用积分
- 0.1405
- 学术水平
- 23 点
- 热心指数
- 25 点
- 信用等级
- 22 点
- 经验
- 3723 点
- 帖子
- 66
- 精华
- 0
- 在线时间
- 62 小时
- 注册时间
- 2009-3-16
- 最后登录
- 2024-4-8
| 悲催 2015-8-6 00:21:31 |
---|
签到天数: 18 天 连续签到: 1 天 [LV.4]偶尔看看III
|
相似文件
换一批
经管之家送您一份
应届毕业生专属福利!
求职就业群
感谢您参与论坛问题回答
经管之家送您两个论坛币!
+2 论坛币
研究生时候写的一个问卷双录入比对程序。程序最开始的说明部分有点罗嗦与模糊请谅解。希望各位网友大能不吝赐教。 - /*功能:完成两数据集排序、找共同记录、比较等功能,并可将结果存入指定的文件中,
- 测试系统:win7
- 测试版本:sas9.2
- 编写人员:dahufa
- 测试人员:dahufa
- 联系方式:dahufa123@126.com
- 权益保护:可以使用不得传播。如有发现问题或有改动联系作者。
- */
- /*
- 宏参数有以下几个:
- base:基础数据集;
- compare:比较的数据集;
- id:两个数据集比较的依据变量,需两组中变量相同
- drop:量比较数据集中不用进行比较的变量,存在多个时彼此间用空格隔开;
- transpose:是否转置,即比较的结果是否以每条记录的方式显示,取值范围为0,1。如为0不转置,以变量方式显示;如为1转置,以变量方式显示。默认为不转置;
- path:比较差异结果输出的全路径,包括盘号:\文件夹\文件名.后缀名。可以省略,省略及不输出。
- 必须定义的变量为base、compare,此时默认比较依据变量为id,不转置,不输出,不去变量。
- */
- /*
- 运行前work中与该程序中间产生的数据集同名的文件需保存。如:
- a、cs、f、s fir1,fir2、fns、sec1、sec2、snf及可能产生的f1、f2、f3……和s1、s2、s3……等。
- 判读结果时可能用到的数据集:
- fir2:base数据集中id号重复的记录;
- sec2:compare数据集中id号重复的记录;
- fns:在base数据集中存在而在compare数据集中不存在的变量;
- snf:在compare数据集中存在而在base数据集中不存在的变量;
- 在校对前需尽可能保证fns与snf中不存在记录,尽可能发现fir2中sec2中id与fir1、sec1相同却不是指一问卷的记录。
- 其余数据集的含义:
- fir1、sec1:base、compare数据集中id第一次出现的记录;
- f、s: base、compare数据集中最后进入比较的记录;
- */
- /*
- 另及小提示:
- 在比较前可以对数据进行一些整理,建议在保留原始记录的基础上用程序进行
- 上述的改动(即都通过程序改动数据,而不直接改动数据集),使用更改后的数据集进行比较,而在校对时在原始记录上改错误,
- 这样如要得到最后的结果跑一遍改动的程序即可。
- */
- %macro compare (base=,compare=,id=id,drop= ,transpose=0,path= );
- %put &base &compare;
- %symdel nw nobs eob;
- /*清除本宏中可能出现的全局宏变量,以防止干扰。运行时就此处出现绿字提示“WARNING: 删除宏变量 NW 失败,未找到该变量。
- ”等乃正常现象,说明系统中没有此宏变量。*/
- %if &transpose=1 %then %let transpose=transpose;
- %else %let transpose=;
- /*程序开始*/
- proc sort data=&base;
- by &id;
- proc sort data=&compare;
- by &id;
- run;
- data fir1 fir2;
- set &base;
- if first.&id then output fir1;
- else output fir2;
- by &id;
- run;
- data sec1 sec2;
- set &compare;
- if first.&id then output sec1;
- else output sec2;
- by &id;
- run;
- data s fns snf;
- merge fir1(in=ok1) sec1(in=ok2);
- by &id;
- if ok1=1 and ok2=1 then output s;
- if ok1=1 and ok2=0 then output fns;
- if ok1=0 and ok2=1 then output snf;
- run;
- data f;
- merge sec1(in=ok1) fir1(in=ok2);
- by &id;
- if ok1=1 and ok2=1 then output f;
- run;
- /*这一段准备数据库,除含宏变量外与普通宏程序完全相同*/
- data _null_;
- if nobs=0 then do;
- call symput('nobs',"0"); /*空集非得如此,非空可直接:data _null_;set f nobs=nobs;call symput('obc',nobs);run;*/
- end;
- else call symput('nobs',put(nobs,best12.));
- stop;
- set f nobs=nobs;
- run;
- %put 两数据集间都存在的id唯一的记录有 &nobs 条;
- /*以上定f是否是空集, &nobs=0为空集。*/
- %if &nobs=0 %then %do;
- %window both color=yellow
- #5 @28 '两个数据集之间没有共同记录!' attr=highlight
- color=red
- #8 @32 '请敲击ENTER键继续' attr=highlight
- color=blue;
- %display both delete;
- %end;
- /*空集直接终止程序,弹出窗口,由用户交互后推出程序。非空执行下面程序*/
- %else %do;
- ods output comparesummary=cs;
- options nodate source linesize=100 pagesize=30000;
- proc compare data=f (drop=&drop )
- compare=s (drop=&drop )
- maxprint=(10000 32767) nodate &transpose;
- id &id;
- run;
- ods output close;
- dm 'clear output';
- /*初步比较了解不等值总数*/
- data _null_;
- set cs;
- where batch contains "部分比较变量不等的观测数";
- call symput('eob',compress(batch,,'kd'));
- run;
- %put 部分比较变量不等的观测数 &eob;
- /*看部分比较变量不等的观测数,如eob为0表完全相等*/
- %if &eob=0 %then %do;
- %window results color=white
- #5 @28 '恭喜你,现在没有发现两遍之间存在差别!' attr=highlight
- color=red
- #8 @40 '请敲击ENTER键继续' attr=highlight
- color=blue;
- %display results delete;
- %end;
- /*完全相等退出程序*/
- %else %do;
- data _null_;
- set cs;
- where batch contains "比较不等值总数";
- call symput('nw',compress(batch,,'kd'));
- run;
- %put 比较不等值总数为 &nw;
- /*找不等值总数*/
- %if &path^= %then %do;
- proc printto print="&path" new;quit;
- %end;
- /*从现在开始如Path为非空,则将结果存入path文件*/
- %let n=%sysevalf(&nw/32767);
- %put 比结果将会是sas容许打印的 &n 倍;
- %if &n<1 %then %do;
- options nodate source linesize=100 pagesize=30000;
- proc compare data=f (drop=&drop )
- compare=s (drop=&drop )
- maxprint=(10000 32767) nodate &transpose;
- id &id;
- title "比较数据集&base. 和&compare. 的结果";
- run;
- proc datasets lib=work nolist;
- delete cs;
- quit;
- %end;
- /*如果sas能一次打印完全则直接打印(sas最多打印32767行),不然分段打印*/
- %else %do;
- %do i=1 %to %eval(&n+1);
- data f&i;
- %if &i=%eval(&n+1) %then %do;
- set f(firstobs=%sysevalf(&nobs*(&i-1)/(&n+1)+1,int) obs=max);
- %end;
- %else %do;
- set f(firstobs=%sysevalf(&nobs*(&i-1)/(&n+1)+1,int) obs=%sysevalf(&nobs*&i/(&n+1),int));
- %end;
- run;
- data s&i;
- %if &i=%eval(&n+1) %then %do;
- set s(firstobs=%sysevalf(&nobs*(&i-1)/(&n+1)+1,int) obs=max);
- %end;
- %else %do;
- set s(firstobs=%sysevalf(&nobs*(&i-1)/(&n+1)+1,int) obs=%sysevalf(&nobs*&i/(&n+1),int));
- %end;
- run;
- /*将数据分段,分段后逐段比较并将结果输出以保证sas将所有错误一次打印完全*/
- options nodate source linesize=100 pagesize=30000;
- proc compare data=f&i (drop=&drop )
- compare=s&i (drop=&drop )
- maxprint=(10000 32767) nodate nosummary &transpose;
- id &id;
- title "比较数据集 &base. 和 &compare. 的结果part&i";
- run;
- proc datasets lib=work nolist;
- delete a cs f1-f%eval(&n+1) s1-s%eval(&n+1);
- quit;
- /*删除中间的数据库*/
- %end;
- %end;
- %if &path^= %then %do;
- Proc printto;quit; /*将结果输出*/
- %end;
- %end;
- %end;
- %mend compare;
- /*
- 调用示例:
- 1.启动sas后第一次调用时先将本文件打开,全选并运行,然后在新建的增强型程序编辑器中写入语句:
- “
- %compare(base=h.firfir,compare=h.secsec,id=id,transpose=0,drop=writer freq,path=g:\sas 比较.txt) ;
- ”
- 上例是所有宏参数都指定的情况,宏参数指定最少的情况如下:
- “
- %compare(base=h.firfir,compare=h.secsec) ;
- ”
- 第二次及以后要调用该宏仅需运行上述语句即可。
- 2.找到本文件存放的路劲如:“d:\sas\compare.sas”,然后在sas程序编辑器中写入:
- “
- %include "d:\sas\compare.sas" ;
- options mfile mprint MLOGICNEST; *此句及下句允许sas在log窗口中显示宏处理后的程序;
- filename mprint 'f:\a.sas' ;
- %compare(base=h.firfir,compare=h.secsec) ;
- ”
- 运行即可。
- 建议选第二种,这样可以保证sas程序不会被随便改动。
- */
- /*另:
- base中的id变量与compare中不同的情况下,最好先改相同再比.
- */
- /*
- 2011.7.13追加更正:
- 1.两数据库间没有共同id记录的情况;
- 2.两数据库间没有找到差别的情况;
- 3.改进了寻找不同值数目的方法。
- */
复制代码其实真正要实现这一比较工作很多其他的工具可以办到,但打印出异同点的就少了许多。再次sas实现该操作也简单,不过sort、merge、compare几个步骤而已,这里面其实是多了个最后的判断罢了。其实没有任何用处,纯粹个人意淫。悲催。
扫码加我 拉你入群
请注明:姓名-公司-职位
以便审核进群资格,未注明则拒绝
|
|
-
总评分: 经验 + 100
论坛币 + 100
学术水平 + 7
热心指数 + 7
信用等级 + 7
查看全部评分
|