【问题标题】:How to retain original value of variable not in BY group when using UPDATE to collapse observations使用UPDATE折叠观察时如何保留不在BY组中的变量的原始值
【发布时间】:2019-07-13 21:58:20
【问题描述】:

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

有什么想法吗?

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

【问题讨论】:

  • 这不只是使用(where = (flag = 1))语句的问题吗?
  • @AdamO 我怀疑这适用于这个用例,但不能概括,OP你能确认一下吗?过滤 flag=1 会是一个解决方案吗?如果没有,您能否扩展您的示例数据以包含该场景?
  • 刚刚试了一下。它仅在没有标志 =1 的多个观察值时才有效。然后 diag_code 变量显示 b / f / i / j,因为 d 和 f 都是 flag = 1,而 f 是最后一个。此外,如果存在没有标记的观察结果,则不会列出这些观察结果,并且这也发生在我的数据集中(但在本示例中未在此处列出)。
  • 编辑问题以包含@AdamO 的部分回答,并在没有标志的示例中包含观察

标签: sas collapse


【解决方案1】:

您需要将 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;

【讨论】:

    【解决方案2】:

    可以使用标志(或状态维护)变量选择组中满足某些条件的第一行。

    这里有两种方法:

    • DOW 循环组,不需要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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-16
      • 2023-01-27
      • 2018-02-07
      • 2015-06-30
      • 2017-02-08
      • 1970-01-01
      相关资源
      最近更新 更多