【问题标题】:SAS 9.4 playing up with IFN function resultsSAS 9.4 使用 IFN 函数结果
【发布时间】:2019-03-11 22:45:09
【问题描述】:

我最近迁移到 SAS 9.4,发现 IFN 和 IFC 函数存在一个奇怪的错误。请参阅下面的代码说明 IFN 功能:

data a;
input b 8.;
datalines;
0.1
150
110
9.1
1
0

;
run;

proc sql;
create table test as 
select b, (IFN(b = .  | b  > 100 | b  < 1 ,1,0)) as f_no_overlap length = 8,
(IFN(b in (.,0) | b > 100 | b  < 1 ,1,0)) as m_overlap length = 8,
(IFN(b in (.,0) | b  < 1 ,1,0)) as u_no_100,
(IFN(b in (0,110) | b  < 1 | b > 100 ,1,0)) as b_no_null,
(IFN(b = 0 | b  < 1 | b > 100 | b= . ,1,0)) as h_last_miss, 
(IFN(b = . | b = 0 | b  < 1 | b > 100,1,0)) as k_first_null,
(IFN(b = 0 | b = . | b  < 1 | b > 100,1,0)) as y_second_null,
(IFN(b = 0 | b  < 1 | b = . | b > 100,1,0)) as l_third_null,
(IFN(b  < 1 | b = 0 | b = . | b > 100,1,0)) as o_first_one from a;
quit; 

我得到以下结果:

SAS 9.3 上的相同代码给出以下结果(这是正确的):

为什么它在 9.4 的相同条件下表现得如此奇怪,主要是它似乎是 NULL in condition 似乎导致了问题。 有没有人遇到过同样的问题?我们有解决方案吗?

【问题讨论】:

  • 如果“NULL”是指“缺失”,请尝试检查缺失值的设置(可能不是“.”)。尝试运行proc options option = missing; run; 并检查日志中显示的值。
  • 由于该代码中没有什么特别需要 SQL 尝试将其重写为数据步骤并在两个版本的 SAS 中运行。另外,您为什么要使用 IFN() 来生成布尔答案?您可以将 ifn(condition,1,0) 替换为 condition,SAS 仍会生成 1 表示真,0 表示假..
  • 您运行的是哪个版本的 SAS?我无法重现 sysvlong= 9.04.01M5P091317 的错误。
  • @Tom - 我在 SAS (r) Proprietary Software Release 9.4 TS1M4 上。既然您提到您没有看到这些错误结果,您能告诉我您使用的是什么版本吗?
  • 我已经发过了。 9.4M5.

标签: sas


【解决方案1】:

关于意外评估结果的讨论是针对在 Windows 10.0.17763 Build 17763 上以 SAS 9.4 TS1M4 运行的代码。

3    proc options;
4    run;

    SAS (r) Proprietary Software Release 9.4  TS1M4

SQL 没有缺失值(..&lt;letter&gt;)的概念,与 DATA Step 和其他 Procs 一样。 SQL 有 NULL 并且 SAS 将缺失值强制转换为 NULL,所以有一个模糊的边缘,你在那里发现了一个问题!

无法正确评估表达式似乎是 9.4 SQL 实现在这种特定情况下处理文字缺失 (.) 值的方式。失败不在IFN,而是传递给IFN的评估!

仅检查逻辑表达式问题似乎与IN 无关。当IN 拆分为一系列ORs 时,会出现类似的意外评估结果。具体的原因似乎是缺少的文字 (.) 出现在表达式中的位置——这反过来又变成了 9.4 SQL 实现内部(解析等)

当两个以上的子表达式并且其中一个使用缺失的 (.) 时,这肯定是一个错误。一种更适合远程或直通处理的适当补救措施是避免在 SQL 中使用缺失文字 (.) 并使用 ANSI 空测试运算符 IS NULLIS NOT NULL

data have;
  b = 9.1;
run;

proc sql;
  create table want as
  select 
  b
  , b in (.,0) | b > 100                      as part1                        /* correct result */
  , b in (.,0)           | b < 1              as part2                        /* correct result */
  ,              b > 100 | b < 1              as part3                        /* correct result */
  , b in (.,0) | b > 100 | b < 1              as parts_null_first             /* INCORRECT result */
  ,              b > 100 | b < 1 | b in (.,0) as parts_null_last              /* INCORRECT result */
  , b=. | b=0  | b > 100 | b < 1              as parts_no_in_null_first       /* INCORRECT result */
  ,       b=0  | b > 100 | b < 1 | b= .       as parts_no_in_null_last        /* correct - weird? */

  , b is null | b=0 | b > 100 | b < 1 as parts_is_null                        /* correct result */

  , calculated part1 | calculated part2 | calculated part3 as calc_parts_in_1_expr /* correct result */

  from have
  ;
quit;

当有问题的表达式位于WHERE caluse 中时,我没有测试是否会发生相同的问题。表达式作为 DATA 步中的赋值不是问题:

data want2;
  set have;
  parts_null_first = b in (.,0) | b > 100 | b < 1 ;                 /* correct result  */
  parts_null_last  =              b > 100 | b < 1 | b in (.,0);     /* correct result */
run;

如果表达式求值“错误”出现在 where 表达式中,那么 where 求值引擎更有可能是根本原因——我相信同一引擎用于 Proc/Data WHERE 语句、Dataset WHERE= 选项和 SQL 求值。

可能有针对这种情况的 SAS Note 或 Hotfix,但我没有去寻找。

关于缺失值测试的另一个讨论可以在 community.sas.com 上的 SAS_Tipster 的"SAS Tip: Use IS MISSING and IS NULL with Numeric or Character Variables" 中找到。重要的一点是在空值的标准测试中使用运算符。

与 WHERE 语句一起使用的 IS MISSING 和 IS NULL 运算符可以处理字符或数字变量。它们还与 NOT 运算符一起使用:

DocumentationIS MISSING predicate 总结为:

测试 SAS 本机数据存储中的 SAS 缺失值。

【讨论】:

  • 呃,这是一个糟糕的错误。
  • 您运行的是哪个版本的 SAS?运行您的代码时我没有发现任何问题。
  • 3 proc options; 4 run; SAS (r) Proprietary Software Release 9.4 TS1M4
  • @Tom- 这是我正在使用的 SAS 版本:SAS (r) Proprietary Software Release 9.4 TS1M4 and proc options option = missing;给我这个:MISSING=。指定要打印缺失数值的字符。
  • 感谢理查德的解释。我想知道空值如何在这里运作良好:proc sql; create table test1 as select b from a where (b = . | b &gt; 100 | b &lt; 1 ); quit; 对于同一个数据集 a,我的 where 子句中有多个 OR 条件,其中一个为 NULL,它给出以下结果:b 0.1 150 110 0 这是正确的,不确定如何'。 '在这里工作得很好,而不是在上面指定的 IFN 条件下。
【解决方案2】:

SAS 回复了这个回复:
关于这个问题,我们现在发布了问题说明 XXXXXX:SAS 9.4TS1M4 中的 IFN 函数存在问题。在这个阶段似乎唯一的规避是升级到更新版本的 SAS,例如 SAS 9.4M5 (TS1M5) 或更高版本。因此,在当前版本中,目前没有针对此问题的修补程序或解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 2017-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多