首页 > 解决方案 > PROC FORMAT 可以用于跨多列的组内求和吗?

问题描述

我有一个约 9 亿行的数据集,每一行代表给定患者在 3 年内的索赔,每个索赔有多达 25 个诊断代码排列为变量,以及一个转换特定子集的键将代码转换为“慢性病”。

像这样:

data claims;
   infile cards;
   input id $ type dg1 $ dg2 $ dg3 $ dg4 $ [...] dg25 $; 
   cards; 
A 40 A123 A234 B345 . [...] .
A 10 A234 . . . . [...] . 
B 40 C567 1234 Z4657 [...] . 
B 40 C567 1233 X4787 [...] . 
; 
run; 

data chrons;
infile cards; 
input chron nm $ code $ ;
cards; 
1 ckd A234
1 ckd C567
1 ckd 1233
2 copd B345
2 copd C233
3 diab A234
3 diab 1234
[...]
55 foo Z4657
55 foo X4787
;
run; 

为了确定条件是否为“慢性”,我必须计算出现条件的索赔数量(在任何 DG 中),不同条件的最低索赔数量不同。

目前我已经使用一个非常笨重的数据步骤完成了这项工作,看起来或多或少像这样:

/* first a SQL loop that puts the codes into macros: */

%macro chron(start,end); 

    proc sql noprint; 
        %do k=&start. %to &end.; 
            select strip(catt("'",code,"'")) 
                into :chron&k. separated by ',' 
            where chron=&k. 
           from chrons; 
        %end;
    quit; 
 %mend; 
 %chron(1,55); 


/* then a double loop array for each of the 55 conditions in any of the 25 vars */

data claims_1yr;
 set claims;
    array dgc(25) dg1-dg25;
    array cond(55) cond1-cond55; 
do i=1 to 55; 
    do j=1 to 25; 
if cond(i) < 1 then do; 
    if dgc(j) in (&&chron&i.) then cond&i.=1; else cond&i.=0;
end;
end; 
run; 

随后是一些 SQL 总和,按索赔数量和基于索赔类型的进一步条件等。一些条件有特殊情况,比如有一个代码列表,如果出现在任何 dg{n} 变量中,则索赔不计入,或要求代码位于前 2 个 dg{n} 空格内。

我想知道是否有一种更简单的方法可以使用 PROC FORMAT(我不是特别熟悉)和 PROC MEANS 或 PROC Summary 来获取摘要数据集,其中每个 ID 都有每个 ID 的索赔数量条件(无论代码在哪个 dg 中)。就计算而言,循环的数量是残酷的;我上次运行它时,花了将近 48 小时才完成。

一位同事建议:

%macro sl(st,end); 
proc sql; 
%do l=&st. %to &end.; 
    create table claims_&l as
     select distinct id, 
     sum(case when (dg1 in (&&chron&l.) or 
    dg2 in (&&chron&l.) or 
    dg3 in (&&chron&l.) or 
    dg4 in (&&chron&l.) [...] or 
    dg25 in (&&chron&l.) then 1 else 0 end) as  chron&l. 
    from claims group by id; 
 %end;
quit;    
 %mend; 
%sl(1,55); 

但这通常会在大约一个小时后导致段错误。

datastep 并不是世界上最糟糕的事情,但我想知道这个谜题是否对任何人来说都很熟悉,或者是否有一个我忽略的明显答案(遗憾的是,不能选择使用 SAS 9.3 以外的任何东西)。

最后的目标是拥有一个如下所示的数据集:

ID   Cond   Claims
A    diab    2
A    copd    1  
A    ckd     2
B    diab    1
B    ckd     2
B    foo     2

或者

ID  cond1   cond2  cond3  [...] cond55
A   2        1       2    [...]   0
B   2        0       1    [...]   2 

nb 平均患者在档案中有约 70 项索赔(有约 1300 万不同的患者)。之前的运行表明,其中约 40% 的人至少患有一种慢性病,其中一半(总数的 20%)患有不止一种慢性病。实际上“拥有”条件是基于在给定时间段内具有相关代码的最小索赔数量(不同条件的不同最小值)。

谢谢!

标签: sasbigdata

解决方案


这在数组中使用“值”并创建 CONDn 变量并按 ID 计数。

data claims;
   infile cards missover;
   input id $ type (dg1-dg5)($); 
   cards; 
A 40 A123 A234 B345
A 10 A234
B 40 C567 1234 Z4657
B 40 C567 1233 X4787
;;;; 
   run; 

data chrons;
   infile cards; 
   input chron nm $ code $;
   cards; 
1 ckd A234
1 ckd C567
1 ckd 1233
2 copd B345
2 copd C233
3 diab A234
3 diab 1234
;;;;
   run; 
filename FT77F001 temp;
data _null_;
   file FT77F001;
   set chrons;
   by chron nm;
   if first.chron then put +3 'Cond' chron '=' @;
   put code :$quote. 'in DG' @;
   if not last.chron then put ' or ' @;
   if last.chron then do;
      put ';' +3 'label Cond' chron '=' nm:$quote. ';';
      end;
   run;

data want1(keep=id cond:) / view=want1;
   set claims;
   array DG[*] dg:;
   %inc FT77F001 / source2;
   run;
proc summary data=want1 nway;
   class id;
   output out=want2(drop=_type_) sum(cond:)=;
   run;
proc print;
   run;

在此处输入图像描述

来自 SAS 日志


推荐阅读