首页 > 解决方案 > 使用UPDATE折叠观察时如何保留不在BY组中的变量的原始值

问题描述

我有一份在特定日期就诊的人员名单,我已经将他们标记为特定诊断。现在我正在尝试折叠这些标志以创建一个每行一个人/一个日期的文件。我找到了一个部分有效的解决方案,使用 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        . 

所以基本上,我想保留 diag_code 从第一个具有标志 = 1 的观察中。我已经尝试使用 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   

有任何想法吗?

编辑:添加 where 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  

标签: sascollapse

解决方案


您需要将 DIAG_CODE 变量移开,以使其不会被 UPDATE 语句更新。您需要创建一个新变量来保留在第一个 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;

您可以在第二步中重新合并第一个 FLAG=1 记录中的 DIAG_CODE 值。

data want ;
  update have(obs=0) have;
  by id id_date;
run;

data want ;
  merge want
        have(keep=id id_date diag_code flag rename=(flag=xflag)
             where=(xflag=1 and not missing(diag_code)))
  ;
  by id id_date;
  if first.id_date;
  drop xflag;
run;

推荐阅读