【问题标题】:Creating a Flag within group meeting two criteria within group in SAS在组内创建满足 SAS 组内两个条件的标志
【发布时间】:2015-01-29 16:32:28
【问题描述】:
data abc;
length datec $19; 
input id $ param $ datec $ _flg $;
daten = input(datec,is8601dt.);
format daten is8601dt.;
cards;
001 ALT 2013-01-20T09:16 Y
001 AST 2013-01-20T09:16 Y
001 ALP 2013-01-20T09:16 Y
001 TSB 2013-01-21T09:14 Y
002 ALT 2013-02-20T08:16 N
002 AST 2013-02-20T08:16 Y
002 ALP 2013-02-20T08:16 Y
002 TSB 2013-02-21T08:14 Y
003 ALT 2013-01-20T09:16 Y
003 AST 2013-01-20T09:16 Y
003 ALP 2013-01-20T09:16 N
003 TSB 2013-01-21T09:14 N
004 ALT 2013-08-19T09:16 N
004 AST 2013-08-20T09:16 N
004 ALP 2013-08-20T09:16 Y
004 TSB 2013-08-20T11:14 Y
004 ALT 2013-08-21T09:00 Y
005 ALT 2013-08-19T11:16 Y
005 AST 2013-08-20T09:16 Y
005 ALP 2013-08-20T12:16 Y
005 TSB 2013-08-20T11:14 Y
006 ALT 2013-08-19T07:16 Y
006 ALT 2013-08-20T08:16 N
006 AST 2013-08-20T08:16 N
006 ALP 2013-08-20T08:14 Y
006 TSB 2013-08-20T08:16 Y
006 TSB 2013-08-20T08:14 Y
007 ALT 2013-08-19T10:16 Y
007 ALT 2013-08-20T08:16 N
007 AST 2013-08-20T08:16 N
007 ALP 2013-08-20T08:14 Y
007 TSB 2013-08-20T08:16 Y
007 TSB 2013-08-21T08:14 Y
;
run;

我需要的是制作一个满足以下条件的标志 (_flg2) 变量。 在 id 中,ALT 或 AST 应在 24 小时窗口内将 _FLG 设为“Y”,ALP 和 TSB 必须将 _FLG 设为“Y”。即在 24 小时内 ALT/AST & ALP & TSB 应为“Y”。

最终数据集将包含每个 id 的一个观察值。 _flg2 变量对于 (001,002,004,005,007) 中的 id 将为“Y”,而对于剩余的 id (003,006) 则缺失。

如果需要进一步澄清,请告诉我。

提前致谢!

我试过的代码如下:

proc sort data=abc out=_1;
    by id datec;
run;

data _2;
    set _1 (where=(_FLG = "Y"));
by id datec;
    if _FLG = "Y" then _flg1 = 1;
run;

proc transpose data=_2 out=_3(drop=_NAME_) ;
    by id datec daten;
    var _flg1;
    id param;
run;

data _4 (keep=id alt ast alp tsb daten dtchk dtdif);
    set _3;
    by id datec daten;
    dtdif=dif(daten)/3600;
    if first.id then dtdif=.;
if . lt dtdif lt 24 then dtchk=daten-dtdif*3600;
    format dtchk datetime.;
run;

data _5 (keep=id daten);
    set _4;
    where dtchk ne .;
    by id daten;
    if last.id;
run;

data _6;
    merge   _4(keep=id alt ast alp tsb daten)
            _4(keep=id alt ast alp tsb daten dtchk
            rename=(daten=refdt dtchk=daten alt=alt24 ast=ast24 alp=alp24     tsb=tsb24) where=(daten ne .))
            _5(in=ina);
    by id daten;
    if not ina;
    altf=max(of alt:);
    astf=max(of ast:);
    alpf=max(of alp:);
    tsbf=max(of tsb:);
    if . lt sum(altf, astf) le 2 and sum(alpf, tsbf) = 2 then _FLG2 = "Y";
run;

【问题讨论】:

  • 你已经尝试过的代码...?
  • 我已经用我正在尝试的代码更新了问题。
  • 你确定 ids 004 和 007 的 flag2 应该是 Y 吗?按照你自己的逻辑,我认为他们不符合条件。
  • @user667489 - 是的,004 和 007 应该将 flag2 设为 Y,因为在 004 的情况下,ALP (2013-08-20T09:16)、TSB (2013-08-20T11:14) 和 ALT (2013-08-21T09:00) 都是 Y 并且在 24 小时窗口内。 007 也是如此,ALT (2013-08-19T10:16)、ALP (2013-08-20T08:14) 和 TSB (2013-08-20T08:16) 或 TSB (2013-08-21T08:14) 都是Y 并且在 24 小时窗口内。

标签: sas


【解决方案1】:

以下数据步骤应该可以工作:

data have;
  input @1 id $3. @5 param $3. @9 date yymmdd10. @20 time time5. @26 FLAG $1.;
  format datetime is8601dt. date yymmdd10. time time5.;
  datetime = dhms(date,hour(time),minute(time),0);
cards;
001 ALT 2013-01-20T09:16 Y
001 AST 2013-01-20T09:16 Y
001 ALP 2013-01-20T09:16 Y
001 TSB 2013-01-21T09:14 Y
002 ALT 2013-02-20T08:16 N
002 AST 2013-02-20T08:16 Y
002 ALP 2013-02-20T08:16 Y
002 TSB 2013-02-21T08:14 Y
003 ALT 2013-01-20T09:16 Y
003 AST 2013-01-20T09:16 Y
003 ALP 2013-01-20T09:16 N
003 TSB 2013-01-21T09:14 N
004 ALT 2013-08-19T09:16 N
004 AST 2013-08-20T09:16 N
004 ALP 2013-08-20T09:16 Y
004 TSB 2013-08-20T11:14 Y
004 ALT 2013-08-21T09:00 Y
005 ALT 2013-08-19T11:16 Y
005 AST 2013-08-20T09:16 Y
005 ALP 2013-08-20T12:16 Y
005 TSB 2013-08-20T11:14 Y
006 ALT 2013-08-19T07:16 Y
006 ALT 2013-08-20T08:16 N
006 AST 2013-08-20T08:16 N
006 ALP 2013-08-20T08:14 Y
006 TSB 2013-08-20T08:16 Y
006 TSB 2013-08-20T08:14 Y
007 ALT 2013-08-19T10:16 Y
007 ALT 2013-08-20T08:16 N
007 AST 2013-08-20T08:16 N
007 ALP 2013-08-20T08:14 Y
007 TSB 2013-08-20T08:16 Y
007 TSB 2013-08-21T08:14 Y
;
run;

proc sort data = have;
  by id date;
run;

data want;
  do until(last.id);
    set have(where = (FLAG = 'Y'));
    by id;
    select(param);
      when('ALT','AST') dt1 = datetime;
      when('ALP')       dt2 = datetime;
      when('TSB')       dt3 = datetime;
    end;
    if intck('dtmin',0,range(of dt1-dt3)) <= 24*60 and nmiss(of dt1-dt3) = 0 then FLAG2 = 'Y';
  end;
  call missing(of dt1-dt3);
  drop dt1-dt3;
run;

假设您的数据集在每个 id 内按日期时间顺序排序,您只需比较必须在同一 24 小时窗口内的每个参数值的最近遇到的日期时间。这避免了很多关于转置、加入表格的多个副本等的麻烦。

【讨论】:

  • 004 和 007 应该将 flag2 设为 Y,因为在 004 的情况下,ALP (2013-08-20T09:16)、TSB (2013-08-20T11:14) 和 ALT (2013-08- 21T09:00) 都是 Y 并且在 24 小时窗口内。 007 也是如此,ALT (2013-08-19T10:16)、ALP (2013-08-20T08:14) 和 TSB (2013-08-20T08:16) 或 TSB (2013-08-21T08:14) 都是Y 并且在 24 小时窗口内。
  • 您提供的代码适用于给定的数据,并且在过滤 flag1="Y" 上的数据后给出了所需的结果(即 Y 表示 001,002,004,005,007)。万分感谢。但我不明白您假设 004 和 007 缺少 flag2 的评论,因为您的代码也为这些 id 提供了 Y...
  • 对此感到抱歉 - 我用来读取原始数据的数据步骤中有一个错误,这意味着它读取 11:00 为 01:00 等。在我修复它匹配所有你的测试用例。
  • 如果只收集日期,请告诉我 intck 函数中的哪些变化,并且 flag2 应该是 Y 仅当 ALT/AST & ALP & TSB 为“Y”时的那些 id同一天?
  • 如果您使用的是日期变量而不是日期时间变量,请尝试使用'day' 而不是'dtmin',或者干脆去掉intck 并使用range(of dt1-dt3) = 0 作为第一个该行的条件。
猜你喜欢
  • 2014-09-26
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 2017-11-27
  • 1970-01-01
  • 1970-01-01
  • 2021-05-27
  • 1970-01-01
相关资源
最近更新 更多