全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 SAS专版
12271 10
2013-04-14
虽然利用查找重复记录的方法之前也讨论过,但是一直以来未进行深入研究和比较,今天对三种常用查重方法进行了一下细化分析,非常实用,供大家参考。

样板数据集如下:
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,会得到不一样的结果。两者差别详细参考http://www2.sas.com/proceedings/sugi30/037-30.pdf。简单地说: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语句最为方便实用,推荐实用。

二维码

扫码加我 拉你入群

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

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

全部回复
2013-4-14 07:58:21
Good summary
二维码

扫码加我 拉你入群

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

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

2013-5-15 00:43:26
很经典
二维码

扫码加我 拉你入群

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

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

2013-7-3 14:16:28
请问楼主,您所介绍的第二点,if first.c then output ex1,我理解的是重复的c都不输入,可是为什么ex1数据集里会有重复的5?然后我把first.b也试了一下,也是一样有一个5是重复的,为什么会这样?我是新手,实践不多,求解答
   
二维码

扫码加我 拉你入群

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

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

2013-7-4 15:58:22
mark
LZ太好了
二维码

扫码加我 拉你入群

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

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

2013-7-5 14:05:13
楼主还在不?求解答……
二维码

扫码加我 拉你入群

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

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

点击查看更多内容…
相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群