欢迎光临散文网 会员登陆 & 注册

我感觉到,全都回来了

2021-09-04 21:03 作者:陆震同学  | 我要投稿

几天不见,继续 SAS training。

quiz

首先给你这样包含 unique subject id 和 各种 date 的数据集,如下,

要求你,先依据这 16 个字符型 date 变量创建对应的数字型 date 变量,需为 date9. 格式;再生成一个新的 date 变量,该变量定义为:第一次出现的比前面的一个日期 >=15 天的日期,即若对于某条记录,dtn_1002-dtn_1001>=15  那么 date 应为 dtn_1002

上 code,

data sv;
   set sv;
   array a_a(*) dt_1001-dt_1015 dt_1999;
   array a_b(*) dtn_1001-dtn_1015 dtn_1999;
   format dtn_1001-dtn_1015 dtn_1999 date9.;
   do i= 1 to dim(a_a,1);
       a_b(i)= input(a_a(i), yymmdd10.);
   end;
   do j= 1 to (dim(a_b,1)-1);
       if a_b(j+1)-a_b(j) >= 15 then do;
           date= put(a_b(j+1), yymmdd10.);
           leave;
       end;
   end;
   keep usubjid dtn_1001-dtn_1015 dtn_1999 date;
run;
proc print data= sv(obs= 2); run;

实现效果如下,

厘清思路

为什么要挑这个 quiz 来讲?主要是看中了里面的 leave statement。

array 我们是熟悉的,我们知道 do 循环是对相同变量多次执行相同操作,而 array 数组则是对不同变量执行相同操作。这里我们将一组变量转成一个 array,来统一转化格式,生成新变量。

要重点说的,就是下面 do 循环中的生成新变量 date 的逻辑。quiz 要取第一个比前一次日期多 15 天的那个日期,取到以后就中止该 subject 后续的日期比较。这里我们用到了 leave,它的作用是:在满足某些条件时彻底中止整体 do 循环(注意,并非当次循环),且不会返回 do statement

我们看 print 出来的第一个 subject,它在 dtn_1011 时才满足条件,因而,date 取到 dtn_1011 的日期,而不会再进行后续的日期比较。借助 leave,我们可以实现同一行数据相邻列之间的相互比较。

不知道同学们有没有感觉到,这是一种行维度上面,类似于 lag 的操作。


我感觉到,全都回来了的评论 (共 条)

分享到微博请遵守国家法律