样板数据集如下:
- data ex;
- input a b c;
- cards;
- 2 2 3
- 2 2 3
- 4 5 6
- 4 5 6
- 4 5 6
- 4 5 6
- 4 4 4
- 4 4 5
- 7 7 8
- 9 5 5
- ;
- run;
具体查重方法如下:
1,sort语句
- proc sort NODUPRECS out=ex1 dupout=ex2;
- by a b ;
- run;
ex1保留的是未重复的记录,ex2保留的是重复的记录。
如果将NODUPRECS换成NODUPKEY,会得到不一样的结果。简单地说:NODUPRECS 比较的是数据集中的所有变量,而NODUPKEY只比较by中列举的变量(也即通常所说的key变量)。 所以如果sort选项为NODUPRECS,上面的程序中将by中列举的变量换成a, 或a b, 或a b c,结果都是一样的。但是如果sort选项为NODUPKEY,结果就完全不一样。
2,data步
前提:需要先对数据进行排序。
- proc sort data=ex;
- by a b c ;
- run;
- data ex1 ex2;
- set ex;
- by a b c;
- if first.c then output ex1;
- else output ex2;
- run;
该过程完全等价于sort语句的选项NODUPKEY,所以first.后面的变量为a, 或b, 或c,结果完全不一样。
如果不想让ex2数据集里面的重复记录多次出现,而是重复记录只出现一次,并统计该重复记录出现的次数。该思路非常经典。可用于查看数据库中按某几个变量定义的重复记录到底有多少条。该思路运用sort是解决不了的,采用data步如下:
- data ex1 ex2;
- set ex;
- by a b c;
- retain n 0;
- if first.c then
- do;
- n=1;
- output ex1;
- end;
- else n+1;
- if last.c and n>=2 then
- output ex2;
- run;
retain的作用:在data步循环执行开始前初始化新变量值,使得在下一次循环前仍使用该初始化值。详细用法参考:http://support.sas.com/publishing/pubcat/chaps/58176.pdf
上述ex2数据集也可以采用freq和summary语句实现,具体如下。
- proc freq data = ex noprint ;
- table a*b*c/ out =ex2 (keep = a b c Count where = (Count > 1)) ;
- run ;
- proc summary data=b nway;
- class a b c;
- output out=c (drop=_type_ where=(_freq_>1));
- run;
上述两程序基本原理是一样的。以summary语句为例,nway所起的作用很大,如果不加nway 的话,那么summary的结果将把所有类型都输出来。所有类型的意思就是,class的3个变量的取值分别存在两种大的分类:缺失和不缺失,而每个变量未缺失的时候又各自有不同的取值。所以,所有类型的意思就是:3个变量,包括取缺失值和不同非缺失值的所有组合。这样的结果肯定不是我们想要的,因为我们想要的是3个变量都不缺失的结果,所以就要加上nway。
3、Sql语句
- proc sql noprint;
- create table ex1 as
- select distinct a, b, c
- from ex;
- quit;
select distinct:选取以关键变量(如上例中的a b c)确定的不同记录,该过程同样等价于sort语句的选项NODUPKEY,所以select distinct后面的变量不同,结果也不同。
同时SQL能更进一步进行频次统计,等价于data步输出的两个数据集功能的合并。
- proc sql noprint;
- create table ex2 as
- select a, b, c,
- count(*) as freq
- from ex
- group by a, b, c;
- quit;
总结以上三类方法,SQL语句最为方便实用,推荐实用。