2015-10-19 66 views
0

我有像下面的数据。sas宏做循环一年多少天

我需要为每个人显示在特定年份生活多少天。

我试了很多做循环,如果宏中的语句。

我工作到很多,但我不能这样做我的手空了,我的心碎了。

*name STARTDATE ENDDATE 

*AAA 17.10.2012 21.11.2013 

*BBB 10.05.2014 15.09.2015 

*CCC 06.04.2010 05.05.2013 

*DDD 07.02.2011 07.02.2013 

*EEE 30.03.2013 30.01.2014 

*FFF 01.01.2010 06.05.2010 

因此,我需要这个

*name STARTDATE ENDDATE DayIn2010 DayIn2011 DayIn2012 DayIn2013 DayIn2014 DayIn2015 

*AAA 17.10.2012 21.11.2013 0 0 75 325 0 0 

*BBB 10.05.2014 15.09.2015 0 0 0 0 235 258 

*CCC 06.04.2010 05.05.2013 269 365 365 125 0 0 

*DDD 07.02.2011 07.02.2013 0 327 365 38 0 0 

*EEE 30.03.2013 30.01.2014 0 0 0 276 30 0 

*FFF 01.01.2010 06.05.2010 125 0 0 0 0 0 

你能帮帮我吗?

+0

请分享您迄今尝试过的代码。即使它不起作用,也可能只需稍作调整。 – user667489

+0

另外,你是否绝对需要使用你指定的宽格式?对于大多数情况,我建议使用长格式 - 即每年一列,每人每年一列,以及他们在那一年居住的天数。 – user667489

+0

hi user667489。 。该代码在我的工作电脑中。如果你明天需要我会派人。不,宽格式不必要,长格式已被赞赏。但无法弄清楚你如何做到这一点。我很初学这个。 – user3375397

回答

1

这里有一种方法可以做到这一点。不需要任何宏,只是一个数据的步骤做循环:

data have; 
input name $3. (STARTDATE ENDDATE) (+1 ddmmyy10.); 
format STARTDATE ENDDATE ddmmyy10.; 
cards; 
AAA 17.10.2012 21.11.2013 
BBB 10.05.2014 15.09.2015 
CCC 06.04.2010 05.05.2013 
DDD 07.02.2011 07.02.2013 
EEE 30.03.2013 30.01.2014 
FFF 01.01.2010 06.05.2010 
; 
run; 

data want; 
    set have; 
    format YEAR_START YEAR_END ddmmyy10.; 
    do YEAR = 2010 to 2015; 
     YEAR_START = mdy(1,1,YEAR); 
     YEAR_END = mdy(12,31,YEAR); 
     DAYS_ALIVE = max(0,min(ENDDATE, YEAR_END) - max(STARTDATE,YEAR_START) + 1); 
     output; 
    end; 
run; 

您需要事先知道的最小和最大年份值在数据集中,这样就可以写入正确的DO循环。如果你不这样做,那么你可以写一些代码来做到这一点。

+0

我想我需要这种宽格式。因为我的数据有点大,这个解决方案使我的数据长10倍。但非常感谢你为这个明智的答案。 – user3375397

+0

如果你没有做任何后续的排序或其他处理,你可以改为创建一个视图 - 只需将'data want'改为'data want/view = want;'。这样它就不会占用任何额外的磁盘空间。 – user667489

+0

如果DAYS_ALIVE> 0然后输出,则可以通过将'output;'更改为'如果DAYS_ALIVE> 0然后输出''来删除所有零天行,这会基于示例数据将其缩小很多。 – user667489

1

以下是另一个选项,您可能不需要提前了解开始/结束年份。

data have; 
input name $3. (STARTDATE ENDDATE) (+1 ddmmyy10.); 
format STARTDATE ENDDATE ddmmyy10.; 
cards; 
AAA 17.10.2012 21.11.2013 
BBB 10.05.2014 15.09.2015 
CCC 06.04.2010 05.05.2013 
DDD 07.02.2011 07.02.2013 
EEE 30.03.2013 30.01.2014 
FFF 01.01.2010 06.05.2010 
; 
run; 

data s1; 
set have; 
do dt=startdate to enddate; 
output; 
end; 
run; 

ods output CrossTabFreqs=s2 (where=(not missing(dt) and not missing(name)) keep=name dt frequency); 
proc freq data=s1; 
tables name*dt/
    NOROW 
     NOCOL 
     NOPERCENT 
     NOCUM; 
format dt year4.; 
run; 

proc sort data=s2; 
by name; 
run; 

PROC TRANSPOSE DATA=s2 
    OUT=want(drop=_name_ _label_) 
    PREFIX=DaysIn 
; 
    BY name; 
    ID dt; 
    VAR Frequency; 

RUN; QUIT