选择多列和其他非连续列来查找重复?

时间:2017-03-10 16:18:17

标签: sas proc-sql datastep

我有一个包含许多列的数据集,如下所示:

ID  Indicator Name   C1 C2 C3....C90
 A    0001    Black   0  1  1.....0
 B    0001    Blue    1  0  0.....1
 B    0002    Blue    1  0  0.....1

某些ID是重复的,因为指标不同,但它们基本上是相同的记录。要查找重复项,我想选择不同的ID,名称,然后选择C1到C90进行检查,因为一些具有相同Id和指标的声明具有不同的C1 ... C90值。

有没有办法通过proc sql或sas数据步骤选择c1 ... c90?似乎我能想到的唯一方法是设置数据集然后删除非必要列,但在实际数据集中,它不仅是指标,而且至少还有15个其他列。

3 个答案:

答案 0 :(得分:1)

如果PROC SQL像其他Procs那样使用:变量名称通配符,那将会很好。当没有其他选择是合理的时,我通常使用宏来选择批量列。这可能适合你:

%macro sel_C(n);
    %do i=1 %to %eval(&n.-1);
        C&i.,
    %end;
    C&n.
%mend sel_C;
proc sql;
    select ID,
           Indicator,
           Name,
           %sel_C(90)
    from have_data;
quit;

答案 1 :(得分:0)

如果我理解正确的问题,最简单的方法是将列连接到一个。从行到行保留该值,您可以跨行比较它以查看它是否相同。

data want;
  set have;
  by id indicator;
  retain last_cols;
  length last_cols $500;
  cols = catx('|',of c1-c90);
  if first.id then call missing(last_cols);
  else do;
    identical = (cols = last_cols); *or whatever check you need to perform;
  end;
  output;
  last_cols = cols;
run;

答案 2 :(得分:0)

有几种不同的方法可以做到这一点,如果实际的列名是C1 - C90,则会更容易。如果您只想删除任何您知道重复的内容,可以使用proc sort

proc sort data=dups out=nodups nodupkey;
by ID Name C1-C90;
run;

nodupkey选项将自动删除by语句中的任何重复项。

或者,如果您想知道哪些记录包含重复项,则可以使用proc summary

proc summary data=dups nway missing;
class ID Name C1-C90;
output out=onlydups(where=(_freq_ > 1));
run;

proc summary创建了两个新变量_type__freq_。如果指定_freq_ > 1,则只输出重复记录。另请注意,这将删除Indicator变量。