首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用数组选择事件日期之前的状态

使用数组选择事件日期之前的状态
EN

Stack Overflow用户
提问于 2022-06-02 15:35:26
回答 3查看 45关注 0票数 1
代码语言:javascript
复制
data test;
Input ID $1. Diagnosed_date :ddmmyy10. medication202001 medication202002 
  medication202003 medication202004;
Format diagnosed_date ddmmyy10.;
Datalines;
A 28/02/2020 0 1 1 1
B 28/02/2020 1 1 1 1
C 30/04/2020 0 0 0 1
:
Run;

嗨,我是SAS的新手。以上是一个临床试验的例子。我正在尝试创建一个额外的变量,显示在他们的diagnosed_date前一个月的药物状态。例如,对于ID = A,我希望选择药物状态为medication202001,而对于ID = C,药物状态选择为medication202003。

注意,变量的命名约定以YYYYMM作为后缀。

我的一个朋友建议可以使用SAS数组来完成这个任务,但是我不知道如何创建这个数组。我试过了,但没走多远。

非常感谢这里的任何反馈。

EN

回答 3

Stack Overflow用户

发布于 2022-06-02 17:07:41

我们可以循环遍历一个数组,并使用vname()函数读取每个变量名的月份部分。我们将从变量的名称中删除所有字母字符,只留下月份部分。我们可以将其转换为SAS日期。

因为我们知道前一个月是什么时候,所以我们只需要将这两个变量放在一起,并为每一行提取变量的值。当SAS读取202001时,它将自动将其与月份的第一个对齐(例如,01JAN 2020)。我们将对前一个diagnosed_date月这样做。

代码语言:javascript
复制
diagnosed_date   last_month   month
28FEB2020        JAN2020      JAN2020 <---- last_month = month. Stop and save the value.
30APR2020        MAR2020      JAN2020
30APR2020        MAR2020      FEB2020
30APR2020        MAR2020      MAR2020 <---- last_month = month. Stop and save the value.

代码:

代码语言:javascript
复制
data want;
    set test;

    array medication_status[*] medication:;

    /* Get the previous month of diagnosed_date and align it to 
       the first day of the month 
    */
    last_month = intnx('month', diagnosed_date, -1, 'B');

    do i = 1 to dim(medication_status);

        /* Get month from var name by removing alphabetic characters 
           and converting to a SAS date 
        */
        month = input(compress(vname(medication_status[i]),,'A'), yymmn6.); 
        
        /* Compare the var's month to the previous month */
        if(month = last_month) then do;
            medication_status_last_month = medication_status[i];

            /* Don't keep checking now that we've found the right date */
            leave;
        end;
    end;

    drop i month last_month;
run;
票数 1
EN

Stack Overflow用户

发布于 2022-06-02 17:20:04

因此,如果连续的月份是连续的,那么最简单的方法就是根据diagnosed_date的值直接访问列。但是,只有当所有内容都对齐或以一种可以在列表中使用变量名的方式命名时,这才有效。如果它们不整齐,这将失败,因为您的变量名称不能很容易地列出在单一的破折号格式。

代码语言:javascript
复制
data want;
  set test;
  array medications medication:;
  diag_month = intck('Month','01JAN2020'd,diagnosed_date);  *actually ONE LESS, but that is helpful for us so we leave it;
  if 0 lt diag_month le dim(medications) then 
    medication_status = medications[diag_month];
run;

intck中的第一个值是一个月的第一天或任何一天,但是我们将在第一个药物列中使用第一个。diag_month是一个偏移量(按设计!)从它的真正价值,因为你想要一个偏移-如果它困扰你,它在技术上是关闭,命名它不同,或使它不关闭(加一个),然后减去以后。

票数 1
EN

Stack Overflow用户

发布于 2022-06-02 17:27:51

这里有一个不同的答案:我在现实生活中所做的事情。

这里的问题是您的数据结构。您通常不希望将数据存储在这样的数组中,在这种数组中,变量的名称意味着什么。这并不是说这是一件可怕的事情或任何事情,但它只是让它更多的工作。很可能这些数据并不是真正以这种方式产生的--即使它是以这种方式出现的,也可能有人将其转换到某个地方--但即使是这样,也很容易将其转换为便于工作的正确结构。

在这里,我们做了一个“药物治疗日期”的水平表。然后,加入该表就很简单了(要么像我一样使用SQL,要么使用merge、散列表、格式,或者.)为了得到你想要的--这很容易调整。

首先,我们将其转换为一个垂直的药物治疗日期级别表:

代码语言:javascript
复制
data test_vert;
  set test;
  array medications medication:;
  do _i = 1 to dim(medications);
    medicationDate = input(substr(vname(medications[_i]),11,6)||'01',YYMMDD8.);
    medicationValue= medications[_i];
    output;
  end;
  format medicationDate ddmmyy10.;
  keep ID Diagnosed_Date medicationDate medicationValue;
run;

然后我们做一个简单的连接来得到我们想要的值。

代码语言:javascript
复制
proc sql;
  create table want as 
    select test.id, test.diagnosed_date, test_vert.medicationDate, test_vert.medicationValue 
        from test
        left join test_vert
            on test.id=test_vert.id
            and intnx('Month',test.diagnosed_date,-1,'b') = test_vert.medicationDate
    ;
 quit;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72478785

复制
相关文章

相似问题

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