【问题标题】:SAS distinct in proc sql vs proc sort nodupkeyproc sql vs proc sort nodupkey中的SAS不同
【发布时间】:2014-01-21 10:26:59
【问题描述】:

我有以下数据集:

data work.dataset;
input a b c;
datalines;
27 93 71 
27 93 72
46 68 75
55 55 33
46 68 68
34 34 32
45 67 88
56 75 22
34 34 32
;
run;

我想从前 2 列中选择所有不同的记录,所以我写道:

proc sql;
create table work.output1 as
select distinct t1.a,
t1.b
from work.dataset t1;
quit;

但现在我想知道 var c 的值在输出中看到的组合 (var a, var b) 旁边的前一组中代表什么值。有没有办法找出来?我尝试了以下 proc sort,但我不知道它是否与在 proc sql 中选择不同记录的方式相同。

proc sort data = work.dataset out = work.output2 NODUPKEY;
by a b;
run;

提前感谢您的帮助。

【问题讨论】:

    标签: sql sorting sas distinct proc


    【解决方案1】:

    PROC SORTNODUPKEY 将始终返回物理第一条记录 - 即,当您列出数据时,c=71 将始终保留。 PROC SQL 不一定会返回任何特定记录;您可以要求minmax,但无论您如何进行查询,您都不能保证第一条记录的排序顺序; SQL 通常会根据需要使用数据以尽可能高效地完成查询。

    如果您担心的话,它们将是相同的,因为它们都返回相同数量的记录。

    您无法在 SQL 中以直接的方式完成完全相同的事情;因为 SQL 没有行排序的概念,所以您必须有一种方法来选择哪个 c(max(c)min(c) 等),或者您必须添加一个行计数器并选择最小值那个。

    例如:

    data work.dataset;
    input a b c;
    rowcounter=_n_;
    datalines;
    27 93 71 
    27 93 72
    46 68 75
    55 55 33
    46 68 68
    34 34 32
    45 67 88
    56 75 22
    34 34 32
    ;
    run;
    
    proc sql;
    select a,b,min(rowcounter*100+c)-min(rowcounter*100) as c
    from work.dataset
    group by a,b;
    quit;
    

    这是在使用作弊(知道 rowcounter*100 将始终支配 c 的大小);当然,如果你的 c 没有合适的值,这将不起作用,你最好单独合并它。

    如果您对 SQL 解决方案感兴趣,可以考虑将其作为单独的问题明确发布,因为只有 SQL 的人会回答。

    【讨论】:

      【解决方案2】:

      NODUPKEY 将为每个键返回一个观察值。在您的示例中,仅保留 a=27 和 b=93 的两个观察值之一。 c=71 或 c=72 将丢失。

      NODUPREC 选项将删除重复记录。将保留 a=27 和 b=93 的两个观测值,但只有 a=34、b=34 和 c=32 值的两个观测值之一。

      【讨论】:

      • 我知道,但问题是我能找出哪个(c=71 或 c=72)被丢弃了。我假设 SAS 保留数据集中“更高”的记录(在此特定示例中,将保留 27 93 71),但需要确认或否认这一点的人。
      • 在 sql select distinct 查询中,没有记录被真正删除,因为变量 c 不是选择的一部分。在 proc sort nodupkey 示例中,SAS 只保留它遇到的第一个观察结果。
      • 感谢您的回答。还有一个,是否有可能执行 proc sql 获取 n 列并仅基于其中的一个子集“区分”它?换句话说,我会将 row_number 添加到我的数据中,选择 a、b 和 row_number,但不同的特征将放在前两列。
      【解决方案3】:

      Sql 不会在上述查询中返回变量 c 的值,因为它没有在 select 语句中列出。我认为您可能正在寻找的是:

      proc sql;
      create table work.output1 as
      select t1.a,
      t1.b,
      min(t1.c) as c
      from work.dataset t1
      group by a, b;
      quit;
      

      如果您想要c 的最大值,那么您可以将该函数替换为max(t1.c) as c,或者使用任何其他sql 函数来选择您的值。如果您想复制 PROC SORT nodupkey 并获取列出的第一个值,则需要使用函数 monotonic (我知道......不受 SAS 支持,但无论如何它都在那里)。你的代码现在是:

      proc sql;
      create table work.output1 as
      select monotonic() as rownum,
      t1.a,
      t1.b,
      t1.c
      from work.dataset t1
      group by a, b
      having calculated(rownum) = min(calculated rownum);
      quit;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多