在 SAS 中的组内创建满足两个条件的标志
Creating a Flag within group meeting two criteria within group in SAS
data abc;
length datec ;
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 小时 window 内将 _FLG 设为 "Y",并且 ALP 和 TSB 必须将 _FLG 设为 "Y"。即在 24 小时内 ALT/AST & ALP & TSB 应该是 "Y".
最终数据集将包含每个 id 一个观察值。对于 (001,002,004,005,007) 中的 id,_flg2 变量将为 "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;
以下数据步骤应该有效:
data have;
input @1 id . @5 param . @9 date yymmdd10. @20 time time5. @26 FLAG .;
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 小时内的每个参数值的最近遇到的日期时间 window.这避免了很多关于转置、加入 table 等
的多个副本的麻烦
data abc;
length datec ;
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 小时 window 内将 _FLG 设为 "Y",并且 ALP 和 TSB 必须将 _FLG 设为 "Y"。即在 24 小时内 ALT/AST & ALP & TSB 应该是 "Y".
最终数据集将包含每个 id 一个观察值。对于 (001,002,004,005,007) 中的 id,_flg2 变量将为 "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;
以下数据步骤应该有效:
data have;
input @1 id . @5 param . @9 date yymmdd10. @20 time time5. @26 FLAG .;
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 小时内的每个参数值的最近遇到的日期时间 window.这避免了很多关于转置、加入 table 等
的多个副本的麻烦