【问题标题】:What does the SAS '/unique' on a set statement actually do?set 语句中的 SAS '/unique' 实际上是做什么的?
【发布时间】:2020-08-22 09:10:30
【问题描述】:

我有一些旧的 SAS 代码要转换成 python。

部分代码有效地做到了这一点:

data A (index=(key1=(record_id, record_version)));
  set table.xxx (where = ...)
run;

data B;
  set table.yyy (where = ...)
  set A key=key1/unique;
    if _ERROR_ = 1 then do;
      valueA = "";
      _ERROR_ = 0;
    end;
run;

我已阅读 SET and UNIQUE 声明的文档,其中说:

默认情况下,SET 仅在 KEY= 值更改时才在索引顶部开始搜索。

如果 KEY= 值在 SET 语句的连续执行中没有改变,则搜索从最近检索到的观察开始。换句话说,当出现连续重复的 KEY= 值时,SET 语句会尝试与正在读取的数据集中的重复索引值进行一对一匹配。如果指定的连续重复 KEY= 值多于正在读取的数据集中存在的重复值,则将多余的重复值视为未找到。

当 KEY= 是唯一值时,只有第一次尝试使用该键值读取观察结果才会成功;随后尝试使用该键值读取观察结果失败。 IORC 变量返回一个对应于 SYSRC 自动调用宏的助记符 _DSENOM 的值。如果添加 /UNIQUE 选项,则后续尝试读取具有唯一 KEY= 值的观察会成功。 IORC 变量返回 0。

嗯,“随后尝试使用该键值读取观察结果失败。”。失败怎么办?

所以实际上,给定 A 和 B 是:

A record_id record_version valueA     B record_id record_version valueB
  1         1              A11          1         1              B10 
  1         1              A12          1         2              B20
  1         2              A22
  1         3              A33 

我的输出肯定会包括这些行:

record_id record_version valueA valueB
1         1              A11    B10
1         2              A22    B20

我不明白if _ERROR_ 语句的作用。

我明白了吗?

record_id record_version valueA valueB
1         1                     B10

还是这个?

record_id record_version valueA valueB
1         1              A12    B10

我明白了吗?

record_id record_version valueA valueB
1         3              A33    null

还是这个?

record_id record_version valueA valueB
1         3                     null

错误语句处理的边缘情况是什么?

【问题讨论】:

    标签: sas


    【解决方案1】:

    当查找表 A 中不存在来自 set table.yyy (where = ...) 数据的键时,代码会将查找值重置为缺失。如果未发生重置,则查找值将是从先前成功查找中检索到的值。

    /UNIUE 告诉 SET 如果有多个可能的检索(即查找表 A 具有重复的 record_id/record_version),它应该检索 first 查找。 在未找到此类查找的情况下,仍需要 _ERROR_ 来重置查找值。

    只有当主表的重复键行数多于非唯一索引查找表的重复键行数时,问题才会真正出现。

    例子:

    * lookup indexed, but not unique;
    * lookup is more typically a 'transaction' table;
    data lookup(index=(IDX_key1key2=(key1 key2)));
    input key1 key2 valueA $; datalines;
    1 1 A11      1st 1 1
    1 1 A12      2nd 1 1
    1 2 A22
    1 3 A33
    ;
    
    data master;
    input key1 key2 valueB $; datalines;
    1 1 B10       1st 1 1 
    1 2 B20
    1 1 B30       1st 1 1 
    1 1 B40       2nd 1 1
    1 1 B50       3rd 1 1
    ;
    
    * data for 2nd 1 1 lookup is from 2nd lookup;
    * data for 3rd 1 1 lookup is from 2nd lookup and PUT will show _ERROR_=1 in log;
    * No _ERROR_ check, that cant be good;
    data master_with_keyed_lookup;
      set b;
      set a key=IDX_key1key2;
    
      put _all_;
    run;
    
    * data retrieved for 2nd and 3rd 1 1 lookup are from 1st lookup row due to unique;
    * No _ERROR_ check, that cant be good;
    data master_with_unique_keyed_lookup;
      set b;
      set a key=IDX_key1key2/unique;
    
      put _all_;
    run;
    

    【讨论】:

    • 我明白了。所以我在我的例子中的理解是否正确,结果集实际上只是:(1,1,A11,B10), (1,2,A22,B20),因为 B 中的键没有重复项?
    • 没错。当您转换为 Python 时,您需要确保 Python 代码选择“第一个”查找并正确处理“未找到”的情况。
    猜你喜欢
    • 2023-03-17
    • 2011-03-11
    • 2010-11-26
    • 2015-06-23
    • 2017-12-26
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多