【问题标题】:How to summarize number of diseases present for different age groups?如何总结不同年龄组存在的疾病数量?
【发布时间】:2020-10-09 23:02:55
【问题描述】:

我有患有多种疾病的人的数据集。这些疾病在不同的时间点发展。

ID  time_ enrolled   Baseline_age dis1 dis1_time dis2 dis2_time dis_3 dis3_time
1     2005.5           35         1     2010.7    1     2012.1   0     2015.3
2     2004.3           49         0     2011.3    1     2013.8   0     2017.9
...

我总结了 30-39、40-49 等每个基线年龄组中患有一种、两种或三种疾病的人的比例。现在我想计算一下有多少人40-49岁时有一种、两种或三种疾病。这个比例将是他们在那个年龄代表所有个人的比例。 首先我想计算他们患上最后一种疾病时的最大年龄,但随后年轻年龄组的类别将为空,年龄较大的组也将为空,例如如果这个人在 70 岁之前患有所有疾病。有没有人有任何想法我该如何解决这个问题?我正在使用 SAS 进行编程。

【问题讨论】:

    标签: sas


    【解决方案1】:

    有几个注意事项:

    • 将数据转置为又高又瘦的结构时,处理更容易
      • 每个 id/疾病标志一行
    • 在某些情况下,该人的年龄范围可能存在“差距”
      • 示例:20-29 岁发病,40-49 岁发病
        这对我来说是 30-39 岁年龄段疾病的隐含零计数。在计算所有 id 中 30-39 的疾病比例时,这种隐含意义很重要(并且应该考虑在内)。
      • 当年龄的标准化值用于某个范围内的年龄时,可以轻松完成“空白”的填充。可以使用自定义格式和自定义信息计算“标准”值。
      • 只应在登记日期和最后一次患病日期之间的年龄范围内添加空白记录

    方法

    • 为每个 id 和注册年龄转置年龄和标志
    • 使用MEANS 对每个id 年龄(标准化)的标志求和,以获取一个年龄范围内的并发疾病计数
    • 左连接交叉连接 ID 和年龄,并填入总和
    • 再次使用MEANS计算年龄和age*flag_count
    • 使用DATA step 计算计数比例[age*flag_count]/[age]

    示例代码

    * custom format and informat for standardizing age;
    
    proc format;
      value agegrp
        20-29 = '20-29'
        30-39 = '30-39'
        40-49 = '40-49'
        50-59 = '50-59'
        60-69 = '60-69'
        70-79 = '70-79'
        80-89 = '80-89'
        90-high = '90 + '
      ;
      invalue agegrp
        '20-29' = 20
        '30-39' = 30
        '40-49' = 40
        '50-59' = 50
        '60-69' = 60
        '70-79' = 70
        '80-89' = 80
        '90 + ' = 90
      ;
    run;
    
    * generate some sample data;
    
    data have;
      call streaminit(123);
     
      do id = 1 to 10000;
        enrolled = '01jan2000'd + rand('integer', 1, 3650);
        age = 20 + rand('integer', 59);
    
        flag1 = rand('uniform') < 0.25;
        date1 = enrolled + rand('integer',2500);
    
        flag2 = rand('uniform') < 0.25;
        date2 = date1 + rand('integer',2500);
    
        flag3 = rand('uniform') < 0.25;
        date3 = date2 + rand('integer',2500);
    
        output;
      end;
      format enrolled date: yymmdd10. flag: 1.;
    run;
    
    * compute age at each disease flag time point;
    
    data stage1;
      set have;
      
      age1 = age + intck('year', enrolled, date1);
      age2 = age + intck('year', enrolled, date2);
      age3 = age + intck('year', enrolled, date3);
    run;
    
    * parallel array based transposition of ages and flags;
    
    data stage2;
      set stage1;
    
      * map age in range to first value in range;
      * need for later when creating zero counts for intermediate age ranges not in data;
      * counts of zero counts needed to compute proportion;
    
      enroll_age = input(put(age,agegrp.),agegrp.);
    
      age = input(put(age1,agegrp.),agegrp.); flag = flag1; output;
      age = input(put(age2,agegrp.),agegrp.); flag = flag2; output;
      age = input(put(age3,agegrp.),agegrp.); flag = flag3; output;
    
      keep id enroll_age age flag;
      format enroll_age age 4. flag 1.;
    run;
    
    ods listing;
    
    * compute number of simultaneous diseases in age range;
    
    proc means noprint nway data=stage2;
      class id enroll_age age;
      format enroll_age age agegrp.;
      var flag;
      output out=stage3(drop= _type_ _freq_) sum=flag_count;
    run;
    
    * data for cross join;
    
    data all_ages;
      do age = 20 to 90 by 10;
        output;
      end;
      format age agegrp.;
    run;
    
    * combine all_ages with each id so as to get a zero count
    * for a range not present between enroll_date and max date;
    
    proc sql;
      create table stage4 as
      select ids.id, ages.age, coalesce(stage3.flag_count,0) as flag_count
      from
        ( select distinct id from stage3 ) as ids
      cross join 
        all_ages as ages
      left join 
        stage3
        on ids.id = stage3.id and ages.age = stage3.age
      group by
        ids.id
      having
        ages.age between min(stage3.enroll_age) and max(stage3.age)
      order by
        ids.id, age
      ;
    quit;
    
    * compute counts;
    
    proc means noprint data=stage4;
      class age flag_count;
      output out=stage5 N(id)=;
      types age age*flag_count;
    run;
    
    * compute proportions;
    
    data want;
      merge
        stage5 (where=(_type_=2) rename=_freq_=age_freq)
        stage5 (where=(_type_=3) rename=_freq_=flag_count_freq)
      ;
      by age;
    
      age_flag_count_proportion = flag_count_freq / age_freq;
    
      format age_flag_count_proportion percent5.;
    
      keep age flag_count age_freq flag_count_freq age_flag_count_proportion;
      format flag_count 1.;
    run;
    

    输出数据示例

    【讨论】:

    • 非常感谢理查德,我想知道是否可以根据性别和地区调整这些比率?
    • 很可能,取决于您的意思 adjust 以及考虑到另外两个分类变量 sex地区。您可能需要为性别和地区创建其他格式和信息。
    • 感谢理查德的解释。另一个问题是,如果我们想找出每个年龄组患有不同疾病组合的人的比例,我们该如何总结?再一次,我已经总结了基线年龄,但现在我想计算一下有多少人,例如在 40-49 岁时患有疾病 1+疾病 2 等。比例将是他们在该年龄时占所有个体的比例。你有什么想法我们该怎么做?我认为它应该与您对疾病数量的想法类似。
    • StackOverflow 中的另一个问题应该作为另一个问题发布。请务必包含所需输出的示例。在 community.sas.com 等网站上进行扩展讨论会更好
    • 我在这里发布了一个新问题:stackoverflow.com/questions/64341318/…,请随意看看
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 2016-04-28
    • 2019-10-31
    • 2017-06-22
    相关资源
    最近更新 更多