Alter berechnen mit Base SAS
Verfasst von ChrisLemberg am 26 Oktober, 2008 - 21:31
Hallo Community,
hoffentlich erscheint mein Beitrag dieses Mal und verschwindet nicht wieder im Nirvana.
Ich habe eine relativ simple Frage, die ich mir selbst nicht beantworten kann, da ich hoffentlich nur den Wald vor lauter Bäumen nicht sehe ...
Ich habe ein Geburtsdatum, das in einer Oracle-Tabelle steht. Von diesem Geburtstag will ich nun das aktuelle Alter ableiten, was ja unter anderem mit Systemdatum - Geburtsdatum funktioniert. Das Resultat dieser Operation sind dann Tage?!
Gibt es eine kleine Lösung um das ganze mit Base zu programmieren oder gibt es etwa eine Funktion, die mir das Ergebnis liefert?
Viele Grüße
Christopher
»
- Anmelden oder Registrieren um Kommentare zu schreiben

Alter-Berechnung in einer Base-Zeile
Hallo Christopher,
es gibt eine kleine Lösung:
/*----------------------------------------------------------------
* Macro: age1
*
* Berechnung des Alters in Jahren, abh. von vorgebenen Datum "_DATE" oder von "heute"
*
* see also:
* SAS communications, 4Q1998,
* Chapter ???, page 38,
* "Accurately calculating age in only one line"
* by William Kreuter
*
* Beispiel für Macro "age1":
* ========
* data xxx;
* age1=%age1( '28dec1956'd , '27dec1999'd );
* age2=%age1(input("19561228", yymmdd8.), '27dec1999'd );
* age3=%age1(input("19561228", yymmdd8.) ); "heute" als Referenz-Datum
* run;
* proc print data=xxx; run;
*
* see also:
* www.sas.com > Service and Support > Technical Tips (20010124)
* http://www.sas.com/service/techtips/quicktips/calcage.html
* Quick Tip: "Accurately calculating age with only one line of code"
* by William Kreuter
*---------------------------------------------------------------*/
%if &_DATE. eq %then %let _DATE="&sysdate."d;
floor(
(intck( 'month', &_BIRTH., &_DATE.)
-
( day(&_DATE.) < day(&_BIRTH.) )
) / 12
)
%mend age1;
Es gibt (natürlich) auch noch eine zweite Lösung:
/*----------------------------------------------------------------
* Macro: age2
*
* Berechnung des Alters in Jahren, abh. von vorgebenen Datum "_DATE" oder von "heute"
*
* see also:
* www.sas.com > Service and Support > Technical Tips (20020405)
* http://www.sas.com/service/techtips/quicktips/age_0302.html
* Quick Tip: "Calculating age in Years and Days"
* by Venky Chakravarthy
*
* Beispiel für Macro "age2":
* ========
* data dates;
* retain birth "02jan2001"d;
* do refer = "31dec2001"d, "01jan2002"d, "02jan2002"d, "03jan2002"d ;
* output;
* end;
* run;
* data _null_;
* set dates;
* %age2(birth, refer );
* put age = "Years and " days "days";
* run;
*---------------------------------------------------------------*/
%if &_DATE. eq %then %let _DATE="&sysdate."d;
age = int (yrdif(&_BIRTH., &_DATE., 'actual'));
days = datdif(mdy(month(&_BIRTH.),day(&_BIRTH.), year(&_DATE.)), &_DATE., 'actual');
if days < 0 then do;
days = datdif(mdy(month(&_BIRTH.),day(&_BIRTH.), year(&_DATE.)-1), &_DATE., 'actual');
end;
%mend age2;
Gruß
Hans Kneilmann, Schäfer Shop GmbH (SSI)
Einfacher?
Hallo,
geht das nicht auch einfacher:
alter=int(yrdif(gebtag,today(),'actual')
bzw.
alter=intck('YEAR',gebtag,today())
Viele Grüße
Thomas
Einfach aber falsch
Hallo,
natürlich geht es auch einfacher, aber das Problem der Alters-Berechnung liegt im Detail.
Beispiel:
Ich habe erst am 28. Dezember Geburstag (genau 28.12.1956).
Bin ich schon 52 Jahre alt? Oder noch 51 Jahre?
Die Antwort ist klar: Ich bin noch 51 Jahre alt.
Die o.a. Lösung meint aber ich wäre schon 52 Jahre alt:
retain birth "28dec1956"d;
do refer = today(), '27dec2008'd , '28dec2008'd, '29dec2008'd ;
output;
end;
run;
data _null_;
set dates;
put "INFO: age : " ;
age=%age1( birth , refer );
put "INFO: age1: " age = "Years ";
%age2( birth , refer );
put "INFO: age2: " age = "Years and " days "days";
alter=int(yrdif(birth,refer,'actual'));
put "INFO: age3: " alter = "Jahre";
alter=intck('YEAR',birth,refer);
put "INFO: age4: " alter = "Jahre";
run;
liefert folgende (teilweise falschen) Ergebnisse:
INFO: age1: age=51 Years
INFO: age2: age=51 Years and 307 days
INFO: age3: alter=51 Jahre
INFO: age4: alter=52 Jahre
INFO: age :
INFO: age1: age=51 Years
INFO: age2: age=51 Years and 365 days
INFO: age3: alter=51 Jahre
INFO: age4: alter=52 Jahre
INFO: age :
INFO: age1: age=52 Years
INFO: age2: age=52 Years and 0 days
INFO: age3: alter=52 Jahre
INFO: age4: alter=52 Jahre
INFO: age :
INFO: age1: age=52 Years
INFO: age2: age=52 Years and 1 days
INFO: age3: alter=52 Jahre
INFO: age4: alter=52 Jahre
Die einfache Lösung aus dem obigen Beitrag von Kotulla (27. Oktober 2008, 2:16) liefert m.E. oft eine falsche Lösung.
Die Macros age1 und age2 aus meinem Beitrag (HansKneilmann,26. Oktober 2008, 21:47) liefern (bei diesen Test-Werten) jedesmal das korrekte Alter.
Gruß
Hans Kneilmann, Schäfer Shop GmbH (SSI)
Hans Kneilmann, Schäfer Shop GmbH (SSI)
Hallo Herr Kneilmann, vielen
Hallo Herr Kneilmann,
vielen Dank für diese Ausführung.
Dann werde ich mir das auch einmal speichern.
Viele Grüße
Thomas
Hallo, ich möchte
Hallo,
ich möchte anschließend zu dem Thema noch eine Frage aufwerfen:
Gibt es auch ein Makro, dass die Altersberechnung wie %age2(geb,heute) realisiert, nur auch die Schaltjahre mit einbezieht?
retain birth "29feb2000"d;
do refer = "28feb2003"d, "01mar2003"d, "28feb2008"d, "29feb2008"d ;
output;
end;
run;
data _null_;
set dates;
%age2(birth, refer );
put age = "Years and " days "days";
run;
Alter wenn Geburtstag am Schalttag
Hallo Herr Knoll,
wenn die Frage sich nur auf das Alter bezieht ist die Antwort ganz einfach:
Ja es gibt ein Makro, dass die Altersberechnung realisiert und auch die Schaltjahre mit einbezieht, nämlich
age=%age1( birth, refer );. Ungefähr so:retain birth "29feb2000"d;
do refer = "28feb2003"d, "01mar2003"d, "28feb2008"d, "29feb2008"d ;
output;
end;
run;
data _null_;
set dates;
age=%age1(birth, refer );
put age = "Years ";
run;
Die Ausgabe ist
age=2 Years
age=3 Years
age=7 Years
age=8 Years
und damit korrekt (oder?)
Nachtrag (14. August 2009, 10:40)
Das Problem bei
%age2( birth, refer );liegt in dem Versuch das Alter tages-genau auszurechnen. Dabei ist aber das Problem, wohin man die Geburttags-Feier verschiebt wenn geerade kein Schaltjahr ist. Und passend zur verschobenen Geburttags-Feier kann man dann die Tages-Differenz zurefer(oder zu heute oder zu ...) ausrechnen.Im Macro
%age2( birth, refer );wird einfach (und ungeprüft) der Tag und der Monat vom (Original-)Geburtstag auf die Folgejahre übertragen .... Und im Jahr 2003 (erster Test-Fall) gibt es keinen 29.02., deshalb meldet SAS im LOG ganz korrektEnde vom Nachtrag
Gruß
Hans Kneilmann, Schäfer Shop GmbH (SSI)