2015-10-19 113 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