繁体   English   中英

SAS 使用 if 语句执行循环

[英]SAS do loop with if statement

我正在尝试按三个月组或季度的数据集进行分组,但由于我从任意日期开始,我不能在 sas 中使用季度 function。

下面我所拥有的和季度的示例数据是我需要在 SAS 中创建的列。 开始日期始终相同,因此我的第一个季度将是 2018 年 9 月 3 日 - 2018 年 12 月 3 日,该季度的任何活动日期都是 1,然后第 2 季度将是 2018 年 12 月 3 日 - 2019 年 3 月 3 日,依此类推。 这不能手动编码,因为开始日期会根据数据而变化,并且季度数可能高达 20+。

到目前为止我尝试过的代码如下

data test_Data_op;
set test_data end=eof;
%let j = 0;
%let start_date = start_Date;
if &start_Date. <= effective_dt < (&start_date. + 90) then quarter = &j.+1;
run;

这有效并正确给出了第一季度,但我不知道如何为接下来的每个季度循环? 任何帮助将不胜感激!

基于@Lee 的评论。 编辑以匹配屏幕截图中的数据。

该示例显示 5 月 11 日将在第 3 季度,因为种子日期是 9 月 3 日。

data have;
input mydate :yymmdd10.;
format mydate yymmddd10.;
datalines;
2018-09-13
2018-12-12
2019-05-11
;
run;

%let start_date='03sep2018'd;

data want;
set have;
quarter=floor(mod((yrdif(&start_date,mydate)*4),4))+1;
run;

如果您希望季度数超过 4(例如,2019 年 9 月 4 日将在第 5 季度,而不是循环回到 1),则从 function 中删除“mod”:

quarter=floor(yrdif(&start_date,mydate)*4)+1;

如果您已经有了 start_date 和实际事件日期,则不需要 DO 循环。 只需计算月数并除以三。 使用 INTCK() function 的连续方法来处理不是一个月的第一天的开始日期。

month_number=intck('month',&start_date,mydate,'cont')+1;
qtr_number=floor((month_number-1)/3)+1;

季度的传统用法是指相对于 1 月 1 日的 3 个月时间段。确保您的听众理解数据演示中的“季度”一词实际上意味着相对于某个任意起点的 3 个月。

可以使用INTCK的混合计算基准月份和用于调整与开始日期的月份中的日期相关的逻辑表达式,从相隔的月份中计算出时髦的季度。 不需要循环。

例如:

data have;
  do startDate = '11feb2019'd ;
    do effectiveDate = startDate to startDate + 21*90;
      output;
    end;
  end;
  format startDate effectiveDate yymmdd10.;
run;

data want;
  set have;

  qtr = 1 
      + floor(
          ( intck ('month', startDate, effectiveDate) 
            -
            (day(effectiveDate) < day(startDate))
          ) 
          / 3
        );

  format qtr 4.;
run;

额外的

将我的方法 ( qtr ) 与 @Tom ( qtr_number ) 的 startDates 范围进行比较:

data have;
  retain seq 0;
  do startDate = '01jan1999'd to '15jan2001'd;
    seq + 1;
    do effectiveDate = startDate to startDate + 21*90;
      output;
    end;
  end;
  format startDate effectiveDate yymmdd10.;
run;

data want;
  set have;

  qtr = 1 
      + floor( ( intck ('month', startDate, effectiveDate) 
                 - (day(effectiveDate) < day(startDate))
               ) / 3 );

  month_number=intck('month',startDate,effectiveDate,'cont')+1;
  qtr_number=floor((month_number-1)/3)+1;

  format qtr: month: 4.;
run;

options nocenter nodate nonumber;title;
ods listing;

proc print data=want;
  where qtr ne qtr_number;
run;

dm 'output';

-------- OUTPUT ---------

                                effective            month_     qtr_
    Obs    seq     startDate          Date     qtr    number    number

  56820     31    1999-01-31    1999-04-30       1        4         2
  57186     31    1999-01-31    2000-04-30       5       16         6
  57551     31    1999-01-31    2001-04-30       9       28        10
  57916     31    1999-01-31    2002-04-30      13       40        14
  58281     31    1999-01-31    2003-04-30      17       52        18
 168391     90    1999-03-31    1999-06-30       1        4         2
 168483     90    1999-03-31    1999-09-30       2        7         3
 168757     90    1999-03-31    2000-06-30       5       16         6
 168849     90    1999-03-31    2000-09-30       6       19         7
 169122     90    1999-03-31    2001-06-30       9       28        10
 169214     90    1999-03-31    2001-09-30      10       31        11
 169487     90    1999-03-31    2002-06-30      13       40        14
 169579     90    1999-03-31    2002-09-30      14       43        15
 169852     90    1999-03-31    2003-06-30      17       52        18
 169944     90    1999-03-31    2003-09-30      18       55        19
 280510    149    1999-05-29    2001-02-28       7       22         8
 280875    149    1999-05-29    2002-02-28      11       34        12
 281240    149    1999-05-29    2003-02-28      15       46        16
 282035    150    1999-05-30    2000-02-29       3       10         4
 282400    150    1999-05-30    2001-02-28       7       22         8
 282765    150    1999-05-30    2002-02-28      11       34        12

暂无
暂无

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

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