繁体   English   中英

使用多个BY组SAS计数观察

[英]Counting observations using multiple BY groups SAS

我正在检查大型EHR数据集中的处方模式。 数据经过结构化,以便为我们提供一些关键的信息,例如Patient_num,遭遇数字,ordering_date,药物,age_event(事件发生的年龄)等。下面的示例:

    Patient_num  enc_num  ordering_date  medication  age_event
        1111     888888     07NOV2008    Wellbutrin     48
        1111     876578     11MAY2011    Bupropion      50
        2222     999999     08DEC2009    Amitriptyline  32
        2222     999999     08DEC2009    Escitalopram   32
        3333     656463     12APR2007    Imipramine     44
        3333     643211     21DEC2008    Zoloft         45
        3333     543213     02FEB2009    Fluoxetine     45

目前,我已按患者编号然后按订购日期对数据集进行了排序,这样我就可以纵向了解每个人在相遇时的处方。 目前,我最关心的是他们初次造访时所开的处方。 我写了一些代码来计算处方的数量,最初将以后的分析限制为RX = 1,但是正如我们所看到的,这对于在同一遭遇中具有多个脚本的人来说是行不通的(患者2222)。

    data pt_meds_;
     set pt_meds;
     by patient_num;
     if first.patient_num then  RX = 1;
     else RX + 1;
    run;

     Patient_num  enc_num  ordering_date  medication  age_event  RX
        1111     888888     07NOV2008    Wellbutrin     48        1
        1111     876578     11MAY2011    Bupropion      50        2
        2222     999999     08DEC2009    Amitriptyline  32        1
        2222     999999     08DEC2009    Escitalopram   32        2
        3333     656463     12APR2007    Imipramine     44        1
        3333     643211     21DEC2008    Zoloft         45        2
        3333     543213     02FEB2009    Fluoxetine     45        3

我认为将遇到的数字重新编码为一个新变量会更合适,以使它们反映类似于RX变量的样式。 每次遇到都以1-n列出的地方,如果在同一次遇到中制作了多个脚本,该数字将重复。 如下面:

     Patient_num  enc_num  ordering_date  medication  age_event  RX   Enc_
        1111     888888     07NOV2008    Wellbutrin     48        1    1
        1111     876578     11MAY2011    Bupropion      50        2    2
        2222     999999     08DEC2009    Amitriptyline  32        1    1 
        2222     999999     08DEC2009    Escitalopram   32        2    1
        3333     656463     12APR2007    Imipramine     44        1    1
        3333     643211     21DEC2008    Zoloft         45        2    2
        3333     543213     02FEB2009    Fluoxetine     45        3    3

从我所看到的,这可能是使用2个BY组(Patient_num和enc_num)的上述代码的变体,但是我似乎无法理解。 我认为第一个。 /最后。 代码需要排序,但是如果我要按enc_num排序,它们将不会按时间顺序排列,因为遇到的次数是由系统生成的,并且取决于当时发生的所有其他遇到的情况。

我尝试执行以下代码(改为使用ordering_date,因为它已经正确排序了),但是Enc_下的所有内容都打印为1。我确定我的逻辑是错误的。 有什么想法吗?

    data pt_meds_test;
     set pt_meds_;
     by patient_num ordering_date;
     if first.patient_num; 
     if first.ordering_date then enc_ = 1;
     else enc_ + 1;
    run; 

第一

如果数据顺序正确或在BY语句中使用NOTSORTED ,则.First / .Last标志不需要排序。 如果BY语句中的变量未正确排序,则BY语句将引发错误并在遇到偏差时停止执行。 像这样:

data class;
   set sashelp.class;
   by age;
   first = first.age;
   last = last.age;
run;

 ERROR: BY variables are not properly sorted on data set SASHELP.CLASS.
 Name=Alfred Sex=M Age=14 Height=69 Weight=112.5 FIRST.Age=1 LAST.Age=1 first=. last=. _ERROR_=1 _N_=1
 NOTE: The SAS System stopped processing this step because of errors.
 NOTE: There were 2 observations read from the data set SASHELP.CLASS.        

试试这个代码来看看如何exacly .first / .last国旗的工作原理:

data pt_meds_test;
   set pt_meds_;
   by patient_num ordering_date;

   fp = first.patient_num;
   lp = last.patient_num;
   fo = first.ordering_date;
   lo = last.ordering_date;
run;

第二

这些条件与您认为的不同:

if expression;
  • 如果expression为true,则在if之后继续下一条指令。
  • 否则,返回数据步骤的开始(无隐式输出)。 这也意味着您的观察未保留在输出中。

在大多数情况下, if没有then等于where 然而

  • where工作更快,但仅限于您正在读取的数据集中的变量
  • if可以与包括计算字段在内的任何类型的表达式一起使用

更多信息: IF语句,子集

第三

我认为lag()函数可能是您的不二之选。

data pt_meds_test;
   set pt_meds_;
   by patient_num;

   retain enc_;

   prev_patient_num = lag(patient_num);
   prev_ordering_date = lag(ordering_date);

   if first.patient_num then enc_ = 1;
   else if patient_num = prev_patient_num and ordering_date ne prev_ordering_date then enc_ + 1;
   end;
run;

使用lag()函数,您可以在previos观测中查看vairalbe的值,然后将其与当前值进行比较。 但是要小心。 lag()不会从先前的观察中寻找变量值。 它接收变量值并将其存储在大小为1的FIFO队列中。在下一次调用时,它从队列中检索存储的值并将新值放在该队列中。 更多信息: LAG功能

我不确定这是否会影响您的其余分析,但是

proc freq data=pt_meds noprint; 
    tables patient_num ordering_date / out=pt_meds_freq;
run;

data pt_meds_freq2;
    set pt_meds_freq;
    by patient_num ordering_date;
    if first.patient_num;
run;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM