【问题标题】:SAS Given a start & end date I need to know the dates of each 30 day period AFTER the first 35 daysSAS 给定一个开始和结束日期,我需要知道前 35 天后每 30 天的日期
【发布时间】:2023-03-08 15:06:01
【问题描述】:

我有 2 个日期,一个开始日期和一个结束日期。

我想知道前 35 天期间的日期,然后是每个后续 30 天期间的日期。

我有;

start       end
22-Jun-15   22-Oct-15
9-Jan-15    15-May-15

我想要;

start       end         tik1        tik2        tik3        tik4
22-Jun-15   22-Oct-15   27-Jul-15   26-Aug-15   25-Sep-15   
9-Jan-15    15-May-15   13-Feb-15   15-Mar-15   14-Apr-15   14-May-15

我对日期计算很好,但我真正的问题是创建一个变量并增加它的名称。我决定包括我的整个问题,因为我认为在它的上下文中可能更容易解释。

【问题讨论】:

  • 你自己目前解决问题的方法是什么?
  • 你可以有一个宏来获取列的值,同时在循环中增加变量名......用你得到的变量创建一个临时表......并与以前的表格合并
  • 你真的想要宽输出格式吗?或者一个狭长的格式也可以工作,即为每个时期生成一个记录,
  • 我想不出任何其他方式来呈现这些信息,所以我希望我需要它,如图所示。这一步目前是手动完成的,因为我不知道我需要创建多少个 tik 列。这些示例是基本的,我希望我可以创建 tik1-tik(x),填充所需的列并删除其余列。更优雅的方法是只创建我需要的列,而不是选择足够大的数字 x 并在找到最后填充的 tik(x) 列时将列放到右侧。

标签: date datetime sas date-range days


【解决方案1】:

您可以通过以下逻辑解决问题:

1) 确定要添加的列数。

2) 根据要求计算列的值

data test;
input start end;
informat start date9. end date9.;
format start date9. end date9.;
datalines;
22-Jun-15 22-Oct-15
09-Jan-15 15-May-15
;
run;

/*******Determining number of columns*******/
data noc_cal;
set test;
no_of_col = floor((end-start)/30);
run;
proc sql;
select max(no_of_col) into: number_of_columns from noc_cal;
run;

/*******Making an array where 1st iteration(tik1) is increased by 35days whereas others are incremented by 30days*******/
data test1;
set test;
array tik tik1-tik%sysfunc(COMPRESS(&number_of_columns.));
format tik: date9.;
tik1 = intnx('DAYS',START,35);
do i= 2 to %sysfunc(COMPRESS(&number_of_columns.));
tik[i]= intnx('DAYS',tik[i-1],30);
if tik[i] > end then tik[i]=.;
end; 
drop i;
run;

替代方式(以防您不想使用 proc sql)

data test;
input start end;
informat start date9. end date9.;
format start date9. end date9.;
datalines;
22-Jun-15 22-Oct-15
09-Jan-15 15-May-15
;
run;

/*******Determining number of columns*******/
data noc_cal;
set test;
no_of_col = floor((end-start)/30);
run;

proc sort data=noc_cal;
by no_of_col;
run;

data _null_;
set noc_cal;
by no_of_col;
if last.no_of_col;
call symputx('number_of_columns',no_of_col);
run;

/*******Making an array where 1st iteration(tik1) is increased by 35days whereas others are incremented by 30days*******/
data test1;
set test;
array tik tik1-tik%sysfunc(COMPRESS(&number_of_columns.));
format tik: date9.;
tik1 = intnx('DAYS',START,35);
do i= 2 to %sysfunc(COMPRESS(&number_of_columns.));
tik[i]= intnx('DAYS',tik[i-1],30);
if tik[i] > end then tik[i]=.;
end; 
drop i;
run;

我的输出:

> **start   |end        |tik1     | tik2     |tik3     |tik4**
> 22Jun2015 |22Oct2015  |27Jul2015| 26Aug2015|25Sep2015|    
> 09Jan2015 |15May2015  |13Feb2015| 15Mar2015|14Apr2015|14May2015

【讨论】:

  • 我需要更多时间来消化这个!输出是需要的,我不喜欢使用 proc sql 但是我可以再次欣赏这种情况下的简洁性。我一定会通过这个扩展我的想法。谢谢!
  • @heroz 如果您不想使用 proc sql,我已经为此添加了替代解决方案。如果您需要代码的详细说明,请告诉我。另外,如果我的回答帮助您解决了您的疑问,请访问链接:stackoverflow.com/help/someone-answers
  • 看起来不错,详细的描述会很有帮助。我最感兴趣的代码是使用 %sysfunc 递增变量名的最后一部分,这将进入我的代码以完成它。
  • number_of_column 存储需要为所需输出创建的列数的值(在本例中为“4”)。 array tik tik1-tik%sysfunc(COMPRESS(&number_of_columns.)); 从 tik1-tik4(in this case) 创建一个列数组。 &number_of_columns. 调用值“4”,compress 是在存储列数的值时删除空格(如果有),因为宏字典中没有列出压缩函数所以要使用压缩功能,我们需要 %sysfunc
  • 太好了,我正在阅读 %sysfunc,我看到了一个与 compress 一起使用的示例。但是不确定为什么在这种情况下需要压缩? &number_of_columns 只是一个很小的数字。
【解决方案2】:

我更喜欢长的垂直结构。我会这样处理它:

data want;
  set have;
  tik=start+35;
  do while(tik<=end);
    output;
    tik=tik+30;
  end;
  format tik mmddyy10.;
run;

如果您真的需要它,您可以在第二步中转置该数据集。

【讨论】:

  • 我不会这样想,但肯定值得进一步探索,因为这看起来很简单。由于使用此信息的方式,广泛是首选,我将研究转置 - 我一直在学习。感谢您提供这个!
  • 我想将此标记为有用,但我不能这样做,因为我的声望很低,对此感到抱歉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多