| 
 | 
楼主
 
 
 楼主 |
发表于 2013-9-26 07:31:58
|
只看该作者
 
 
 
SAS中如何删除重复记录
现有一堆数据,里面有很多是重复的,要去掉?要重新保留成另外的数据集? 
2 2 3 
2 2 3 
4 5 6 
4 5 6 
4 5 6 
4 5 6 
4 4 4 
7 7 8 
9 5 5 
我想去掉里面重复的观察值,实现的四种方法: 
1,proc语句 
2,sql语句(之所以单独出来,是因为sql本来都强大,可以独顶一方) 
3,data步 
4,hash对象方法 
第一种,PROC 两种方法: 
1,SAS语句proc sort: 
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; 
proc sort NODUPRECS out=ex1 DUPOUT=ex2; 
by a b ; 
run; 
不重复的保留在数据集ex1里面,重复的保留在数据集ex2里面。 
这里重复有两种情况,如果指定关键词with by的重复的操作的话,那么sort的option:NODUPRECS要换成NODUPKEY,这样得出的结果是两种不同的情况。 
2,SAS语句SUMMARY, 
第二种,PROC SQL,有多种途径: 
proc sql noprint; 
   create table res as 
      select distinct time1 from temp311e; 
quit; 
第三种,DATA步内微操作,(这样操作有个前提,就是此数据集需要进行排序或者已经排好序了)。 
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; 
proc sort; 
by a b c ; 
run; 
data ex1 ex2; 
   set ex; 
   by a b c; 
   retain n 0; 
   if first.c then output ex1; 
    else output ex2; 
   run; 
这只是一个DATA步而已,并没有表现出“微操作”的特性,如果我们需要的重复记录的数据集里面的记录不重复,怎么办?是否需要在对重复记录的重复记录再操作一次? 
这个问题用DATA步的微操作可以一步实现: 
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; 
proc sort; 
by a b c ; 
run; 
data ex1 ex2; 
   set ex; 
   by a b c; 
   retain n 0; 
   if first.c then do; 
                      n=0; 
                      output ex1; 
                   end; 
         n+1; 
               else output ex2; 
   if last.c and n ge 2 then output ex2; 
   run; 
这样的结果,好像proc sort不能一步晚成。 
其实这个DATA步是一个经典的DATA步,用于很多场合,非常稳定有效,让人满意。 
 
 /*代码的测试deleteDuplicate.sas*/ 
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 data=ex NODUPRECS out=ex1 DUPOUT=ex2; 
by a b ; 
run; 
 
/*NODUPKEY只要key不重复*/ 
proc sort data=ex NODUPKEY out=ex1 DUPOUT=ex2; 
by a b ; 
run; 
 
/*2. Sql过程*/ 
proc sql noprint; 
     create table res as 
  select distinct a,c 
  from ex; 
quit; 
 
/*sql也可以计算频度*/ 
proc sql noprint; 
     create table res as 
  select a,c,count(*) as freq 
  from ex 
  group by a,c; 
quit; 
 
/*3. 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; 
 
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; 
 
/*4. Data步使重复数据集的记录不重复*/ 
proc sort data=ex; 
by a b c ; 
run; 
/*对原代码稍作修改后*/ 
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 ge 2 then output ex2; 
run; |   
 
 
 
 |