首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何按开始日期/结束日期对的时间顺序排列SAS数据集

如何按开始日期/结束日期对的时间顺序排列SAS数据集
EN

Stack Overflow用户
提问于 2020-04-10 18:02:00
回答 1查看 700关注 0票数 1

我有一个相当混乱的数据集,有200多条记录(参与者),许多列表示参与者所处的待遇,以及该处理的开始日期和结束日期。

下面是我的数据集中一小部分的示例,其中PATID是参与者id,x1DRG是药物(1或2),x1SDT是他们开始服用该药物的日期,x1EDT是他们停止使用的日期。其余的列也是一样。

例如,对于第一次记录的x1DRG=2 (参与者服用了药物2 ),从X1SDT=11/6/2019开始,没有x1EDT (意思是他正在服用),x2DRG仍然是2岁,药物在x2SDT = 12/7/2016开始,药物在x2EDT = 1/9/2017时终止,最后x3DRG (仍然2)在x3SDT=1/9/2017和x3 the =6/5/2018年再次开始。

我想要做的是,根据这些开始和结束的日期,看看有多少参与者停止了研究药物。因此,我最终会得到一个SAS数据集和参与者ID,一个包含1或0的停止列,基于他是否停止了药物,一个包含停药的药物列(1或2),一个如果他不停止的话,他正在使用的当前药物的列,以及一个列,如果他停止了它,他就有停药的日期。例如,对于PATID 1,停止列为0(没有停止),当前药物为2,停止日期为空,因为他仍在使用药物2。对于PATID 6,我们将停止为1(他停止),药物将为1,当前药物将为空(目前没有任何药物),停止日期为11/24/2019。

我想做的是转换数据集,然后做一些类似的事情,如果对每个参与者来说,最老的结束日期之后没有一个开始日期,那就意味着参与者没有停止治疗。

但是,问题在于,正如您所看到的,对于一些参与者(以红色突出显示的行、第1、7、8、9行),开始日期和结束日期的顺序并不是按时间顺序排列的。例如,对于参与者1,序列中最古老的开始日期是x2SDT (2016年7月12日),他第一次开始服用药物2,然后在x2EDT (1/9/2017)中停下来,然后在x3SDT (1/9/2017)上再次开始,在x3EDT (6/5/2018)上停止,最后在x1SDT(11/6/2019)上重新开始,现在使用药物2,因为没有x1EDT。所以,在这种情况下和其他很多情况下,x1SDT不符合最古老的日期,因为它应该是这样的,所以你必须用视觉检查序列,找出正确的顺序,并在此基础上,决定他是否还在吸毒。现在,考虑到我有近500张唱片,我显然不想(也没有时间)手动查看所有记录并做出决定。我已经想了好几天了,但不幸的是,我还处于SAS的初级阶段,还没有想出如何通过编程来解决这个问题。如果有人为我提供任何示例代码/建议,我将非常感激!

所以,我在考虑最后的数据集,也许我能得到这样的数据集?虽然不确定这是否有可能,或者是任何一种方式,但只要我能够得到程序来满足我的需要,最终的格式就不会有多大影响。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-11 03:58:41

假设混乱的数据是从Excel导入SAS的。

通常,该数据形状来自数据输入工作表,该工作表集中于病人的行概念,或从存储在其他地方的分类数据创建的枢轴表。

代码语言:javascript
运行
复制
data have; * slightly tweaked data;
attrib
  patid length=8
  x1drg informat=best8. x1sdt x1edt format=mmddyy10. informat=anydtdte.
  x2drg informat=best8. x2sdt x2edt format=mmddyy10. informat=anydtdte.
  x3drg informat=best8. x3sdt x3edt format=mmddyy10. informat=anydtdte.
  x4drg informat=best8. x4sdt x4edt format=mmddyy10. informat=anydtdte.
  x5drg informat=best8. x5sdt x5edt format=mmddyy10. informat=anydtdte.
  x6drg informat=best8. x6sdt x6edt format=mmddyy10. informat=anydtdte.
;
infile datalines missover;
input patid -- x6edt;
datalines;
1 2 11/06/2019 .           2 12/07/2016 01/09/2017  2 01/09/2017 06/05/2018
2 2 11/06/2019 .           . .          .           . 
3 1 01/06/2019 .           . .          .           .
4 2 12/20/2019 02/12/2020  1 03/03/2020 .           .
5 1 11/11/2019 .           . .          .           .
6 1 06/03/2019 11/15/2019  1 11/24/2019 11/24/2019  .
7 2 03/27/2019 .           2 05/08/2018 03/27/2019  2 04/18/2018 05/08/2018  2 04/12/2018 04/18/2018
8 1 06/25/2019 .           2 06/07/2019 06/24/2019  2 01/16/2019 06/07/2019  1 09/20/2018 01/15/2019
9 2 08/09/2019 12/06/2019  2 05/08/2019 08/08/2019  2 12/07/2019 12/07/2019  2 12/08/2019 01/15/2020  2 01/16/2020 01/19/2020  2 01/25/2020 .
;

您希望将数据重组为有四列的结构;PatId drug start_dt end_dtProc TRANSPOSE没有一个语法可以直接将M列的N个行分组转到M列的N行。您可以使用一种称为数据步骤数组旋转的方法。这句话你可以在会议文件中找到,但在SAS文档中却找不到。

示例:

6组3个变量按行向旋转。使用由6个元素组成的3个数组来排列原始变量,以便于重新塑造。

代码语言:javascript
运行
复制
* transpose by data step array method;
data have_categorical;
  set have;

  array drugs  x1drg x2drg x3drg x4drg x5drg x6drg;
  array starts x1sdt x2sdt x3sdt x4sdt x5sdt x6sdt;
  array ends   x1edt x2edt x3edt x4edt x5edt x6edt;

  do index = 1 to dim(drugs);
    drug = drugs(index);
    start_dt = starts(index);
    end_dt = ends(index);

    if not missing(drug) then OUTPUT;
  end;

  attrib start_dt end_dt format=yymmdd10. informat=anydtdte.;

  keep patid drug start_dt end_dt;
run;

一旦数据以分类的形式出现,您就可以在数据步骤、PROC步骤或SQL中进行BY组处理。

您的日期范围似乎相互排斥--换句话说,没有任何日期范围与另一个日期范围重叠。如果可能出现重叠,处理就会更加复杂。此外,病人似乎只有一种有效的药物,其中终止日期是缺失的。

对数据进行排序,以消除原始的日期排序。

代码语言:javascript
运行
复制
proc sort data=have;
  by patid start_dt end_dt;
run;

使用BY组处理为患者的最后一个日期范围分配日期、顺序序列号和状态变量及标志。

代码语言:javascript
运行
复制
data want;
  set have;
  by patid;

  if first.patid
    then seqNum = 1;  * row is first date range for patid, reset sequence number;
    else seqNum + 1;  * row is next date range for patid, increment sequence number;

  if last.patid then do;
    * set the flag value at the last date range of patid;
    * presume EDT will be either missing (open range, still using), or
    * the date when usage stopped;

    stop_date = EDT;

    if missing(EDT) then do;
      STOP = 0;
      CURRENT_DRUG = DRUG;
    end;
    else 
       STOP = 1;
  end;

  format stop_date mmddyy10. seqnum stop current_drug 4.;
run;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61146022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档