用一些变量对连续观察值求和

时间:2017-07-27 21:19:24

标签: sas retain

我刚学会使用SAS,所以请耐心等待一下。我有以下关于处方用法的患者数据样本,我想尝试将观察结果组合起来形成更多患者故事,但保持时间表的完整性:

data have;
 input dose $2. id $4. supply date $8.;
 datalines;
 "5" 1234 30 01012015
 "10" 1234 30 02012015
 "10" 1234 30 03012015
 "5" 1234 30 04012015
 "2" 1234 30 05012015
 "5" 4321 30 07012016
 "2" 9876 30 05012016
 "2" 9876 30 06012016
 "10" 9876 30 07012016
 ;
run;

剂量是mg的剂量,id是患者ID,供应是天数'供应药物,日期是补充药物的日期。

我想巩固一些观察结果,以便当我们观察患者1234时,我们可以看到他们服用5mg 30天,然后10mg服用60天,然后再服用5mg服用30天等。我所学习的所有总和和分组将观察1和4结合在一起,但患者的故事是剂量增加然后减少,我想保持完整但不要#&# 39;不知道如何。

所以它看起来像这样:

data want;
 input dose $2. id $4. supply date $8.;
 datalines;
 "5" 1234 30 01012015
 "10" 1234 60 02012015
 "5" 1234 30 04012015
 "2" 1234 30 05012015
 "5" 4321 30 07012016
 "2" 9876 60 05012016
 "10" 9876 30 07012016
 ;
run;

观察观察3卷入2,8到7等

任何提示都将不胜感激!

2 个答案:

答案 0 :(得分:1)

另一种方法使用NOTSORTED选项,该选项不需要任何有关数据集的预定知识。

data have;
informat date mmddyy8.;
format date date9.;
 input dose  id $ supply date ;
 datalines;
5 1234 30 01012015
10 1234 30 02012015
10 1234 30 03012015
5 1234 30 04012015
2 1234 30 05012015
5 4321 30 07012016
2 9876 30 05012016
2 9876 30 06012016
10 9876 30 07012016
 ;
run;

proc sort data=have;
  by id date;
run;

data want;
set have;
by id dose notsorted;
retain n_days;

if first.dose or first.id then n_days=0;

n_days+supply;

if last.dose then output;

run;

答案 1 :(得分:0)

这是一个依赖于保留变量的解决方案。它只是众多中的一种,它采用了相当先进的技术,可以吓跑初学者的废话。你已被警告;)

使用goto&标签(以:结尾)并不常见,在大多数情况下都可以避免。但在这样的情况下,似乎有必要,主要是为了简洁。

data have;
  informat id 4. dose 3. supply 3. date mmddyy8.;
  format date mmddyy10.;
  input id dose supply date;
  datalines;
1234  5 30 01012015
1234 10 30 02012015
1234 10 30 03012015
1234  5 30 04012015
1234  2 30 05012015
4321  5 30 07012016
9876  2 30 05012016
9876  2 30 06012016
9876 10 30 07012016
;

我们首先确保我们的数据已正确排序。

proc sort data=have;
  by id date;
run;

解决方案

retain语句将使得声明变量的值保留在内存中,因为数据步骤会迭代have数据集的行。

请注意,_i后缀会添加到have i 的现有变量中,代表输入

data want(drop=id_i dose_i supply_i date_i);
  format id dose supply 8. date mmddyy10.;
  retain id dose supply date;
  set have(rename=(id=id_i dose=dose_i supply=supply_i date=date_i)) end=last;

  if _N_ = 1 then goto propagate;

  if id_i = id and dose_i = dose then do;
    supply = supply + supply_i;
    goto checklast;
  end;

  * When id or dose is different from previous row, ;
  * we write the observation to the want table.     ;
  output;

  propagate:
  id     = id_i;
  dose   = dose_i;
  supply = supply_i;
  date   = date_i;

  checklast:
  if last then output;
run;

这里需要注意的一些事项:

  • _N_是一个自动SAS变量,表示当前的迭代次数
  • end=last(用作set语句的参数)创建一个名为last的变量(这是一个任意名称),当该值为1时最后一次观察是从have读取的,否则是0。我们在数据步骤结束时将它用作布尔变量。
  • 请记住,在尝试解决这个问题时,数据步骤就像for循环一样,迭代其源表的行。

结果

id    dose   supply    date
1234    5       30    01/01/2015
1234    10      60    02/01/2015
1234    5       30    04/01/2015
1234    2       30    05/01/2015
4321    5       30    07/01/2016
9876    2       60    05/01/2016
9876    10      30    07/01/2016