【问题标题】:How to remove duplicated records\observations WITHOUT sorting in SAS?如何删除重复的记录\观察而不在 SAS 中排序?
【发布时间】:2011-08-07 14:01:32
【问题描述】:

我想知道是否有一种方法可以不进行排序来取消重复记录?有时,我想保持原始顺序,只是想删除重复的记录。

有可能吗?

顺便说一句,以下是我所知道的关于不重复记录的内容,最终会进行排序..

1.

proc sql;
   create table yourdata_nodupe as
   select distinct *
   From abc;
quit;

2.

proc sort data=YOURDATA nodupkey;    
    by var1 var2 var3 var4 var5;    
run;

【问题讨论】:

  • 目前被什么索引?我敢肯定,即使在以不同的方式对 DB 行进行排序之后,您也可以轻松地按您想要的顺序检索数据库行。

标签: sorting sas duplicates


【解决方案1】:

原帖中给出的两个例子并不完全相同。

  • proc sql 中的 distinct 仅删除完全相同的行
  • proc sort 中的nodupkey 删除关键变量相同的任何行(即使其他变量不相同)。您需要使用 noduprecs 选项来删除完全相同的行。

如果您只是寻找具有共同关键变量的记录,我能想到的另一种解决方案是创建一个仅包含关键变量的数据集,并找出哪些是重复的,然后在原始数据上应用格式标记重复记录的数据。如果数据集中存在多个关键变量,则需要创建一个包含所有关键变量值串联的新变量 - 如果需要,转换为字符。

【讨论】:

  • 请不要“签名”您的帖子。您的个人资料会自动添加到帖子中,您可以在个人资料中链接到您的网站。
【解决方案2】:

请参阅使用说明 37581:如何在不排序的情况下从大型数据集中消除重复的观察结果http://support.sas.com/kb/37/581.html。使用说明 37581 展示了如何在不使用排序的情况下使用 PROC Summary 来更有效地删除重复项。

【讨论】:

    【解决方案3】:
    data output;
    set yourdata;
    by var notsorted;
    if first.var then output;
    run;
    

    这不会对数据进行排序,但会删除每个组中的重复数据。

    【讨论】:

      【解决方案4】:

      这是我能想到的最快的方法。它不需要排序。

      data output_data_name;
          set input_data_name (
              sortedby = person_id stay
              keep =
                  person_id
                  stay
                  ... more variables ...);
          by person_id stay;
          if first.stay > 0 then output;
      run;
      

      【讨论】:

        【解决方案5】:

        根据数据集中变量的数量,以下方法可能是可行的:

        data abc_nodup;
           set abc;
           retain _var1 _var2 _var3 _var4;
           if _n_ eq 1 then output;
           else do;
              if (var1 eq _var1) and (var2 eq _var2) and
                 (var3 eq _var3) and (var4 eq _var4)
                 then delete;
              else output;
           end;
           _var1 = var1;
           _var2 = var2;
           _var3 = var3;
           _var4 = var4;
           drop _var:;
        run;
        

        【讨论】:

          【解决方案6】:

          您可以使用散列对象来跟踪在您通过数据集时已看到哪些值。仅在遇到尚未观察到的键时才输出。这将按照在输入数据集中观察数据的顺序输出。

          这是一个使用输入数据集“sashelp.cars”的示例。原始数据按 Make 的字母顺序排列,因此您可以看到输出数据集“nodupes”保持相同的顺序。

          data nodupes (drop=rc);;
            length Make $13.;
          
            declare hash found_keys();
              found_keys.definekey('Make');
              found_keys.definedone();
          
            do while (not done);
              set sashelp.cars end=done;
              rc=found_keys.check();
              if rc^=0 then do;      
                rc=found_keys.add(); 
                output;              
              end;
            end;
            stop;
          run;
          
          proc print data=nodupes;run;
          

          【讨论】:

            【解决方案7】:

            我认为简短的回答是否定的,至少没有一种方法不会比基于排序的方法对性能产生更大的影响。

            在某些特定情况下,这是可能的(所有变量都被索引的数据集?一个相对较小的数据集,您可以合理地加载到内存中并在那里使用?)但这不会帮助您使用通用方法。

            类似于 Chris J 的解决方案可能是获得您所追求的结果的最佳方式,但这不是您实际问题的答案。

            【讨论】:

            • 是的,有可能 - cmjohns 的答案是正确的并且确实回答了这个问题。它将完全按照 OP 的要求执行,并且使用的开销比排序少。只要确保关键是所有变量的连接,你就可以开始了。
            • 你说得对 Rob,我指的是@Chris J 的回答;当我发布我的答案时,@cmjohns 的好解决方案并不存在。
            【解决方案8】:
            /* 给出原始数据集中的每条记录和行号 */ 带有_id的数据; 设置我的数据; _id = _n_ ; 跑步 ; /* 删除骗子 */ proc sort data=with_id nodupkey ; 通过 var1 var2 var3 ; 跑步 ; /* 重新排序到原来的顺序 */ proc 排序数据=with_id ; 通过 _id ; 跑步 ;

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2019-01-29
              • 2017-01-05
              • 1970-01-01
              • 1970-01-01
              • 2013-06-21
              • 1970-01-01
              • 2016-01-03
              • 2022-07-13
              相关资源
              最近更新 更多