【问题标题】:SAS IFN function gets stuckSAS IFN 功能卡住
【发布时间】:2021-07-31 17:24:54
【问题描述】:

在我们回答我的问题之前,请注意我故意没有在这篇文章中包含示例数据,因为我的问题出现在我的完整数据集及其子集上。我有两个数据集,其中包含以下格式的客户端数据。

Have_1
+------------+------------+------+
|     dt     |   dt_next  |  id  |
+------------+------------+------+
| 30.09.2010 | 31.10.2010 | 0001 |
+------------+------------+------+
| 31.10.2010 | 30.11.2010 | 0001 |
+------------+------------+------+
| 30.11.2010 | 31.12.2010 | 0001 |
+------------+------------+------+
| 31.12.2010 | 31.01.2011 | 0001 |
+------------+------------+------+

Have_2
+------+-------+------------+------------+
| id   | event | start_date | end_date   |
+------+-------+------------+------------+
| 0001 | 1     | 31.10.2010 | 30.11.2010 |
+------+-------+------------+------------+
| 0001 | 2     | 31.10.2010 | 31.12.2010 |
+------+-------+------------+------------+

我正在尝试使用 IFN 函数通过以下逻辑在我的数据集中放置 1-0 个标志:

    Proc SQL;
    Create table want as
    Select a.*
          ,ifn(a.id in (select id from have_2 where a.dt <= end_date and start_date <= a.dt_next), 1, 0) as flg_1
          ,ifn(a.id in (select id from have_2 where a.dt <= end_date and start_date <= a.dt), 1, 0) as flg_2
    From have_1 as a;
    Quit;

如果我只使用一个客户端,代码可以正常工作,但是,如果我使用完整的数据集(甚至是它的一小部分,例如只有 10 个客户端),那么代码就会卡住,因为流程开始时没有错误但根本就没有完成。我尝试为我的两个输入数据集设置索引,但没有成功。 IFN 功能是否有任何特殊性,可以使其行为如此?

【问题讨论】:

  • IFN() 在这段代码中什么都不做,SAS 已经将布尔表达式评估为 1 (true) 或 0 (false)。您的问题与子查询有关。这两个子查询试图找到什么?为什么是子查询而不是普通的连接?
  • 使用这个函数的目的是为了让代码更简洁。我曾经通过连接进行此计算,这需要两个 PROC SQL 语句。如果我可以只使用一个代码块,为什么要使用两个代码块,而不会损失太多的可读性?
  • 我不明白你要计算什么。请用文字解释您要标记什么?
  • 您的表格中有多少行?对于不需要ifn 的标志,只需使用已经为 false~0 true~1 的逻辑评估。您似乎正在检查存在条件,而不是编码 in 。 EXISTS 可以更快。

标签: sas enterprise-guide


【解决方案1】:

那么,如果任何活动的日期属于这些时期,为什么不直接加入并获取所有活动的最大值呢?这应该消除了为 HAVE1 中的每个观察执行两个子查询的需要。

proc sql;
  create table want2 as
  select a.id
       , a.dt
       , a.dt_next
       , max(a.dt <= b.end_date and b.start_date <= a.dt_next) as flg1
       , max(a.dt <= b.end_date and b.start_date <= a.dt) as flg2
  from have1 a 
  left join have2 b
  on a.id = b.id
  group by 1,2,3
  ;
quit;

请注意,问题在于子查询,而不是 IFN() 函数调用。这里也不需要 IFN() 函数。 SAS 将布尔表达式计算为 1 或 0。因此表达式 a=b 返回的结果与 IFN(a=b,1,0) 返回的结果相同。

【讨论】:

  • 代码计算客户的 1 年默认标志和当前默认状态。换句话说,Flg1 表示 have_2 中的事件将在从 have_1 中的当前日期开始的下一年发生。 flg2 表示事件已经开始。该解决方案适用于给定的示例,谢谢!但是,如果我的原始表 (have_1) 有一堆我不能包含在 GROUP BY 子句中的其他列怎么办?如果我使用此代码,它将导致重复值,这就是我使用 IFN() 的原因,因为否则我将需要另一个代码块来清除重复项。
  • 如果您包含既不是键也不是聚合的列,那么 SAS 会将聚合值重新合并到所有详细信息行。对于这个问题,只要在 SELECT 关键字后面加上 DISTINCT 关键字,重复的行就会被删除。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多