我试图根据开始和结束日期对数组中的变量求和。对于每个ID,有一行(如果开始日期和结束日期在同一年内),两行(如果开始日期和结束日期在同一年内),或者有多行用于不同的开始日期和结束日期。每个月有12个变量的计数,即v1-v12,其中v1是1月,v12是12月。某些ID的两行包含连续2年(即统计年和结束年内)的每月值。我正在尝试获取数组变量的总计数,但仅从每个ID的开始日期到结束日期。例如,对于ID 1,开始日期是2007年7月23日,结束日期是2008年7月7日,我想将2007年的V7(七月开始月份)汇总到v12,将V1汇总到V6(六月结束月份)在2008年,即第二排。这是我所拥有的:
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;
但是有问题。任何帮助表示赞赏。谢谢。
答案 0 :(得分:1)
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;
答案不能解决startdate
内enddate
至id
间隔的情况。
答案 1 :(得分:1)
由于每个观测值都代表一年,因此直接的方法是将月份从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