我有一个在特定日期进行医疗就诊的人员列表,并且我已经标记了他们进行特定的诊断。现在,我尝试折叠这些标志,以创建每行一个人/一个日期的文件。我已经找到了使用UPDATE的部分解决方案(在这里找到:SAS collapse dates)。但是,这会用特定日期的某个人的最后诊断代码覆盖标记的诊断代码。这是我的数据的简化版本:
data have;
input id id_date diag_code $ flag;
datalines;
1 1 a .
1 1 b 1
1 1 c .
1 2 d 1
1 2 e .
1 2 f 1
2 1 g .
2 1 h .
2 1 i 1
2 2 j 1
3 1 k .
;
run;
data want;
update have (obs=0) have;
by id id_date;
run;
输出:
diag_
Obs id id_date code flag
1 1 1 c 1
2 1 2 f 1
3 2 1 i 1
4 2 2 j 1
5 3 1 k .
我想要得到的是:
diag_
Obs id id_date code flag
1 1 1 b 1
2 1 2 d 1
3 2 1 i 1
4 2 2 j 1
5 3 1 k .
因此,基本上,我想从具有flag = 1的第一个观察结果中保留diag_code。我尝试过使用RENAME选项来防止覆盖该变量,但是由于UPDATE首先从观察值为0的数据集中读取数据,因此(新)原始变量显示出来但为空:
data want;
update have (obs=0 rename=(diag_code=orig_diag_code)) have;
by id id_date;
run;
orig_
diag_ diag_
Obs id id_date code flag code
1 1 1 1 c
2 1 2 1 f
3 2 1 1 i
4 2 2 1 j
5 3 1 . k
有什么想法吗?
编辑: 仍然添加flag = 1仍会错误地显示出现多个标志时的最后诊断,并且在缺少标志时不会产生有关日期的观察结果:
data want;
update have (obs=0) have;
by id id_date;
where flag=1;
run;
diag_
Obs id id_date code flag
1 1 1 b 1
2 1 2 f 1
3 2 1 i 1
4 2 2 j 1
答案 0 :(得分:1)
您需要将DIAG_CODE变量移开,以免UPDATE语句更新它。您需要创建一个新变量以保留在第一个FLAG = 1记录中找到的值。然后将正确的值重新分配给DIAG_CODE。
#
您可以在第二步中重新合并第一个FLAG = 1记录中的DIAG_CODE值。
data want;
update have (obs=0) have(rename=(diag_code=diag_code_orig));
by id id_date;
if 0 then keep_diag=diag_code ;
retain keep_diag ;
if first.id_date then call missing(keep_diag);
if flag=1 then keep_diag=coalescec(keep_diag,diag_code_orig);
diag_code=coalescec(keep_diag,diag_code_orig);
drop keep_diag diag_code_orig;
run;
答案 1 :(得分:1)
可以使用标志(或状态维护)变量来选择满足某些条件的组中的第一行。
有两种方法:
retain
或first.
retain
,first.
和last.
的隐式循环代码:
* DOW over group with last., no retain or first.;
data want;
do _n_ = 1 by 1 until (last.id_date);
set have;
by id id_date;
if flag and not flagged then do;
output;
flagged = _n_;
end;
end;
if not flagged then output;
drop flagged;
run;
* Only implicit loop with retain, first. and last.;
data want;
retain flagged;
drop flagged;
set have;
by id id_date;
if first.id_date then flagged = .;
if flag and not flagged then do;
flagged = 1;
output;
end;
if last.id_date and not flagged then
output;
run;