根据间隔(即开始日期和结束日期)对 SAS 阵列求和



我正在尝试根据开始和结束日期对数组中的变量求和。对于每个 ID,有一行(如果开始日期和结束日期在同一年内(、两行(如果开始日期和结束日期在连续几年内(或多行用于不同期间的开始日期和结束日期。每个月有 12 个变量的计数,即 v1-v12,其中 v1 是 1 月,v12 是 12 月。某些 ID 的两行包含连续 2 年的月度值,即统计年和结束年。我正在尝试获取数组变量的总和计数,但仅限于每个 ID 的开始日期到结束日期。例如,对于ID 1,开始日期是07/23/2007,结束日期是06/07/2008,我想从2007年的V7(7月开始月(到v12和2008年的V1到V6(6月结束月(,即第二行。 这是我所拥有的:

ID  STARTDATE   ENDDATE      YR    V1  V2  V3  V4  V5  V6  V7  V8  V9  V10 V11 V12
1   07/23/2007  06/07/2008  2007    3   5   2   6   3   2   1   3   4   1   2   3
1   07/23/2007  06/07/2008  2008    0   4   2   2   3   0   1   3   1   0   2   3
2   02/01/2002  07/27/2002  2002    1   0   2   3   1   0   1   2   3   0   0   2
3   05/26/2008  03/07/2009  2008    2   0   2   3   1   2   1   1   3   0   0   1
3   05/26/2008  03/07/2009  2009    4   1   4   3   1   0   2   3   3   1   0   3
3   10/17/2011  08/17/2012  2011    3   3   0   1   0   1   1   5   3   1   0   1
3   10/17/2011  08/17/2012  2012    1   3   2   3   1   0   1   2   3   2   0   2
4   02/27/2004  01/22/2005  2004    2   0   2   3   1   2   1   1   3   0   0   1
4   02/27/2004  01/22/2005  2005    0   4   2   2   3   0   1   3   1   0   2   3

这就是我想要的:

ID  STARTDATE   ENDDATE      YR    V1  V2  V3  V4  V5  V6  V7  V8  V9  V10  V11  V12  sum
1   07/23/2007  06/07/2008  2007    3   5   2   6   3   2  [1   3   4    1    2    3]  25
1   07/23/2007  06/07/2008  2008   [0   4   2   2   3   0]  1   3   1    0    2    3   25
2   02/01/2002  07/27/2002  2002    1  [0   2   3   1   0   1]  2   3    0    0    2    8
3   05/26/2008  03/07/2009  2008    2   0   2   3  [1   2   1   1   3    0    0    1]  18
3   05/26/2008  03/07/2009  2009   [4   1   4]  3   1   0   2   3   3    1    0    3   18
3   10/17/2011  08/17/2012  2011    3   3   0   1   0   1   1   5   3   [1    0    1]  15
3   10/17/2011  08/17/2012  2011   [1   3   2   3   1   0   1   2]  3    2    0    2   15
4   02/27/2004  01/22/2005  2004    2  [0   2   3   1   2   1   1   3    0    0    1]  14
4   02/27/2004  01/22/2005  2005   [0]  4   2   2   3   0   1   3   1    0    2    3   14

这是我尝试的代码

data want;
set have;
array vars(*) V1-V12;
DT_CHECK=intnx('month',ENDDATE,-12);
start=intck('month','STARTDATE,DT_CHECK)+1;
if start<1 then do;
error 'Start date out of range';
delete;
end;
else if start>dim(vars)-12 then do;
error 'End date out of range';
delete;
end;
do _N_=start to start+12;
sum_n+vars(_N_);
end;
format DT_CHECK mmddyy10.;
run;

但是我有问题。任何帮助,不胜感激。谢谢。

DOW/串行循环技术可以计算组中的条件值,然后将该值应用于组中的每一行。

例:

要求id内的开始到结束日期间隔相互排斥(即不重叠,数据排序by id startdate enddate(

data want;
* [sum] variable is implicitly reset to missing at the top of the step.;
do _n_ = 1 by 1 until (last.enddate);
set have;
by id startdate enddate;
array v(12);
_month1 = intnx('month', startdate, 0);
_month2 = intnx('month', enddate,   0);
do _index = 1 to 12;
if _month1 <= mdy(_index,1,yr) <= _month2 then sum = sum(sum,v(_index));
end;
end;
do _n_ = 1 to _n_;
set have;
output;
end;
format sum 4.;
drop _:;
run;

答案没有解决startdateenddate间隔在id内重叠的情况。

由于每个观察值代表一年,因此直接的方法是从 1 月到 12 月循环月份,并检查该月份是否在您的日期范围内。

data want;
do until(last.startdate);
set have;
by id startdate;
array v v1-v12;
do month=1 to 12 ;
if intnx('month',startdate,0,'b')<=mdy(month,1,yr)<=intnx('month',enddate,0,'e')
then sum=sum(sum,v[month])
;
end;
end;
keep id startdate enddate sum;
run;

结果:

Obs    ID     STARTDATE       ENDDATE    sum
1     1     2007-07-23    2008-06-07     25
2     2     2002-02-01    2002-07-27      7
3     3     2008-05-26    2009-03-07     18
4     3     2011-10-17    2012-08-17     15
5     4     2004-02-27    2005-01-22     14

最新更新