【问题标题】:Dropping observations after a certain condition is met in SAS在 SAS 中满足特定条件后丢弃观察值
【发布时间】:2020-02-21 11:32:27
【问题描述】:

这是对先前问题的扩展。 (Drop observations once condition is met by multiple variables)。

我有以下数据并使用现有的已回答问题之一来解决我的数据问题,但无法得到我想要的。这是我的数据中的内容

  • 当 Evt_type 为 Fee 时填充 Amt1
  • 当 Evt_type 为 REF1/REF2 时填充 Amt2
  • 我不想在最后一个 Flag='Y' 之后显示任何观察结果
  • 如果没有 Flag='Y',那么我想要该 id 的所有观察结果(例如 id=102)
  • 我想显示该 id 的下一行是否是费用,然后在 flag='Y' 之后是 REF1/REF2(例如 id=101)但是如果没有 REF1/REF2,我不想要(例如 id=103)

有:

   id   Date        Evt_Type   Flag   Amt1   Amt2
  101  2/2/2019      Fee              5
  101  2/3/2019      REF1      Y             5
  101  2/4/2019      Fee              10
  101  2/6/2019      REF2      Y             10
  101  2/7/2019      Fee               4
  101  2/8/2019      REF1
  102  2/2/2019      Fee              25
  102  2/2/2019      REF1      N      25
  103  2/3/2019      Fee              10
  103  2/4/2019      REF1      Y             10
  103  2/5/2019      Fee              10

想要:

  id   Date        Evt_Type   Flag   Amt1   Amt2
 101  2/2/2019      Fee              5
 101  2/3/2019      REF1      Y             5
 101  2/4/2019      Fee              10
 101  2/6/2019      REF2      Y             10
 101  2/7/2019      Fee               4
 101  2/8/2019      REF1
 102  2/2/2019      Fee              25
 102  2/2/2019      REF1      N      25
 103  2/3/2019      Fee              10
 103  2/4/2019      REF1      Y             10

我尝试了以下

data want;
  _max_n_with_Y = 1e12;

  do _n_ = 1 by 1 until (last.id);
    set have;
    by id;
  if flag='Y' then _max_n_with_Y = _n_;
 end;

  do _n_ = 1 to _n_;
   set have;
   if _n_ <= _max_n_with_Y then OUTPUT;
  end;
 drop _:;
run;

感谢任何帮助。

谢谢

【问题讨论】:

  • 在组 103 中,组中的最后一个 Y 行有一个后续的 Fee,但后面没有 Ref# -- 为什么Want 组 103 在 Y 之后有费用?在第 101 组中,您在最后一行 Y 之后显示 Want 两行 - 这不符合问题条件“如果该 ID 的 下一行 是费用,我想显示后跟 REF#。
  • 我的错。我将其更正为 103。但对于 101,在 flag='Y'(第 5 行和第 6 行)之后是费用,后跟 Ref1,所以我希望这些在我的数据中

标签: sas delete-row retain


【解决方案1】:

重要的“地标”是flag='Y' 所在的行

输出行的额外标准地标后使被编码以跟踪(或计算)行号(_n_)的最后输出的状态机复杂化组。

row='Y' 状态很容易知道。无条件使用LAG 可用于检查后Y 状态。 SAS IF 语句没有短路评估,因此只要 LAG 不在从属 THEN 子句中,LAG 堆栈将适用于该任务。

例子:

data have;
attrib
  id format=4.
  date informat=mmddyy10. format=mmddyy10.
  evt_type length=$4
  flag length=$1
  amt1 amt2 format=4.
;
input
   id   Date        Evt_Type   Flag   Amt1   Amt2; datalines;
  101  2/2/2019      Fee       .      5      .
  101  2/3/2019      REF1      Y      .      5
  101  2/4/2019      Fee       .      10     .
  101  2/6/2019      REF2      Y      .      10
  101  2/7/2019      Fee       .       4     .
  101  2/8/2019      REF1      .      .      .
  102  2/2/2019      Fee       .      25     .
  102  2/2/2019      REF1      N      25     .
  103  2/3/2019      Fee       .      10     .
  103  2/4/2019      REF1      Y      .      10
  103  2/5/2019      Fee       .      10     .
;

data want;
  _y_n = 1e12;

  do _n_ = 1 by 1 until (last.id);
    set have;
    by id;

    if flag='Y' then _y_n = _n_;

    /* rule: post Y output of two rows should only occur once, and at the rows
     * immediately succeeding the Y row
     */
    if _n_ = _y_n + 2            /* is this row 2 after a Y */
      and lag(evt_type) = 'Fee'  /* is first row after Y Fee */
      and evt_type =: 'REF'      /* is second row after Y REF# */
    then 
      _upto_n = _n_;
  end;

  _upto_n = max (_upto_n, _y_n);

  do _n_ = 1 to _n_;
   set have;
   if _n_ <= _upto_n then OUTPUT;
  end;

  drop _:;
run;

注意,关于:

if _n_ = _y_n + 2            /* is this row 2 after a Y */
  and lag(evt_type) = 'Fee'  /* is first row after Y Fee */
  and evt_type =: 'REF'      /* is second row after Y REF# */
then 
  _upto_n = _n_;

对于Y之后的第2行,

  LAG2(<var>) is the <var> value from the Y row
  LAG (<var>) is the <var> value from the Y row+1
       <var>  is the <var> value from the Y row+2, which is the current row

【讨论】:

  • 感谢 Richard.. _y_n+2 只检查“Y”之后的 2 行。这可以是动态的吗?有时是'Y'后面的2行或4行
  • 所以,你真的希望,在每个组中,直到最后一个 flag="Y" 的所有行以及直到最后一个 evt_typerow-pair "Fee 的所有后续行/REF#" ?如果是这样,只需将_n_ = _y_n + 2 的相等测试更改为&gt;=
猜你喜欢
  • 2014-10-09
  • 2020-03-30
  • 1970-01-01
  • 2016-01-29
  • 1970-01-01
  • 2020-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多