使用超过50个变量从SAS数据集创建重复表

时间:2015-06-10 15:21:12

标签: duplicates sas

我需要加载到Teradata中的大型SAS数据集(54个变量和超过1000万个观测值)。还有重复项,并且我的机器没有配置为MultiLoad。我想简单地创建一个包含300,000个重复项的表,我可以附加到不接受它们的原始加载。我在其他帖子中读到的逻辑对于只有几个变量的表来说似乎很好。是否有另一种方法可以创建一个新表,其中列出了具有所有54个变量的相同组合的每个观察。我试图通过使用54个变量的逻辑来避免proc排序。查询构建器方法似乎效率低下。感谢。

4 个答案:

答案 0 :(得分:1)

使用proc sort是一种很好的方法,你只需要创建一种更好的方法来关闭它。

创建一些测试数据。

data have;
  x = 1;
  y = 'a';
  output; 
  output;
  x = 2;
  output;
run;

创建一个新字段,该字段基本上等同于将行中的所有字段附加在一起,然后通过md5()(散列)算法运行它们。这将为您提供一个很好的短字段,它将唯一地标识该行上所有值的组合。

data temp;
  length hash $16;
  set have;
  hash = md5(cats(of _all_));
run;

现在使用proc sort和我们的新哈希字段作为键。将重复记录输出到名为'想要':

的表中
proc sort data=temp nodupkey dupout=want;
  by hash;
run;

答案 1 :(得分:0)

您可以这样做:

proc sql;
create table rem_dups as 
select <key_fields>, count(*) from duplicates
group by <key_fields>
having count(*) > 1;
quit; 

proc sql; 
create table target as 
select dp.* from duplicates dp 
left join rem_dups rd 
on <Key_fields>
where <key_fields> is null;
quit; 

如果重复次数超过300K,则此选项不起作用。而且,我不敢说我​​不知道​​Teradata和你加载表格的方式。

答案 2 :(得分:0)

首先,提出一些sort相关建议,然后是休息后的核心“快速”建议。

如果表格完全未排序(即重复项可以出现在数据集中的任何位置),那么proc sort可能是您最简单的选项。如果您有一个密钥可以保证将重复记录放在一起,那么您可以这样做:

proc sort data=have out=uniques noduprec dupout=dups;
  by <key>;
run;

这将在辅助数据集(上面的noduprec)中放置重复记录(注意nodupkey而非dups - 这要求所有54个变量相同)。但是,如果它们在物理上并不相邻(即key有4个或5个重复,但只有两个完全重复),如果它们不是物理上相邻的话,它可能无法捕获;您需要第二种排序,或者您需要列出by语句中的所有变量(可能很混乱)。您也可以使用Rob的md5技术来简化这一点。

如果表格未“排序”但重复的记录将相邻,则您可以by使用notsorted选项。

data uniques dups;
  set have;
  by <all 54 variables> notsorted;
  if not (first.<last variable in the list>) then output dups;
  else output uniques;
run;

如果事情的顺序不正确,那就告诉SAS不要抱怨,但是让你先使用/最后一次。不是一个很好的选择,特别是因为你需要指定一切。

执行此操作的最快方法可能是使用哈希表, iff 您有足够的RAM来处理它,或者您可以以某种方式破坏表(不会丢失重复项) )。 10m行乘以54(比如说10个字节)变量意味着5.4GB的数据,所以这只有在你有5.4GB的RAM可用于制作散列表的情况下才有效。

如果您知道54个变量的子集足以验证唯一性,那么unique哈希只需要包含那些变量子集(即,它可能只有四个或五个索引变量)。 dups哈希表必须包含所有变量(因为它将用于输出重复项)。

这可以通过使用modify来快速处理数据集,而不是重写大部分观察结果;使用remove删除它们和哈希表output方法将重复项输出到新数据集。 unq哈希表仅用于查找 - 因此,它也可以包含变量的子集。

我还使用了一种技术将完整的变量列表转换为宏变量,因此您不必输入54个变量。

data class;   *make some dummy data with a few true duplicates;
  set sashelp.class;
  if age=15 then output;
  output;
run;

proc sql;
  select quote(name) 
    into :namelist separated by ','
    from dictionary.columns
    where libname='WORK' and memname='CLASS'
  ;  *note UPCASE names almost always here;
quit;

data class;
  if 0 then set class;
  if _n_=1 then do;               *make a pair of hash tables;
     declare hash unq();
     unq.defineKey(&namelist.);
     unq.defineData(&namelist.);
     unq.defineDone();
     declare hash dup(multidata:'y'); *the latter allows this to have dups in it (if your dups can have dups);
     dup.defineKey(&namelist.);
     dup.defineData(&namelist.);
     dup.defineDone();
  end;
  modify class end=eof;
  rc_c = unq.check();           *check to see if it is in the unique hash;
  if rc_c ne 0 then unq.add();  *if it is not, add it;
  else do;                      *otherwise add it to the duplicate hash and mark to remove it;
    dup.add();
    delete_check=1;
  end;

  if eof then do;                      *if you are at the end, output the dups;
    rc_d = dup.output(dataset:'work.dups');
  end;

  if delete_check eq 1 then remove;        *actually remove it from unique dataset;
run;

答案 3 :(得分:-2)

我建议您将Proc sortindex一起使用,而不是试图避免proc排序。

Read the document about index

我确信必须有标识符来区分_n_以外的观察, 在索引的帮助下,按noduprecsnodupkey dupout = dataset排序将是一种有效的选择。此外,索引还可以促进其他操作,例如合并/报告。

无论如何,我不认为拥有1000万个观测数据(每个?)的数据集是一个很好的数据集,更不用说54个变量了。