Expertentipp:
 

Wussten Sie schon, wie man Datumswerte in der Vergangenheit oder in der Zukunft berechnen kann?

Und so geht's:

Berechnen von Datumswerten in der Vergangenheit oder in der Zukunft mit SAS

In den sozialen Medien, z.B. Facebook bekommt man immer wieder Erinnerungen an Vergangenes angezeigt. Beispielsweise Fotos die genau vor einer bestimmten Anzahl von Jahren gepostet wurden. Hierfür werden ganz einfache Berechnungen mit Datumswerten durchgeführt.

Mit SAS Datumswerte in der Vergangenheit berechnen

Wofür könnte man so etwas benötigen? Für Auswertungen hat man oft die Fragestellungen: Was hat sich in den letzten 30 Tagen ereignet? Oder: Was hat sich in den letzten 6 Monaten verändert?

30 Tage zurück zu gehen ist einfach: Da ein SAS Datum ja als Anzahl Tag seit dem Basisdatum 1.1.1960 gespeichert ist, kann man folgendes rechnen: today()-30.

Aufwendiger ist es 6 Monate zurückzugehen. Da die Anzahl der Tage pro Monat unterschiedlich ist, wäre eine Subtraktion zu unflexibel. Aber SAS bietet eine Funktion, mit der von einem Startdatum jedes beliebige andere Datum berechnet werden kann. Die Funktion heißt INTNX.

Hier sehen Sie ein Beispiel, das den SAS Datumswert 6 Monate vor dem aktuellen Datum berechnet. Das Beispiel kann im DATA Schritt verwendet werden:


six_mo_ago = intnx(
 'month',  /* Zeitintervall */
  today(), /* Startdatum */
  -6,      /* Anzahl Intervalle, negative Werte gehen in die Vergangenheit */
  'same'   /* Justieren des Datums innerhalb des Intervalls. 
              "Same": Gleicher Tag innerhalb des Monats */
 );

Wenn man jetzt 6 Jahre in die Vergangenheit gehen will, wird das erste Argument ersetzt durch 'year'. 6 Wochen? Verwenden Sie als Intervall 'week'. Hier finden Sie die (sehr lange) Liste mit möglichen Datumsintervallen.

Verwenden von INTNX in der SAS Makrosprache

Oft ist es jedoch sinnvoll, den Wert in eine Makrovariable zu speichern, damit man ihn schrittübergreifend nutzen kann. Dafür verwenden wir die Makrofunktion %SYSFUNC, um die beiden SAS Funktionen (INTNX und TODAY) auf Makroebene ausführen zu können. Außerdem müssen die Anführungszeichen beim Intervall und beim Parameter „same“ entfernt werden, da der Makroprozessor sowieso alles als Text behandelt.


%let six_mo_ago = 
 %sysfunc(
  intnx(
   month,             /* Zeitintervall */
   %sysfunc(today()), /* Ermitteln des aktuellen Datums als Startdatum */
   -6,                /* Anzahl Intervalle, 
                         negative Werte gehen in die Vergangenheit */
   same               /* Justieren des Datums innerhalb des Intervalls. 
                         "Same": Gleicher Tag innerhalb des Monats */
   )
  );
 %put &=six_mo_ago;

Ergebnis (am 16.1.2018 ausgeführt):


45          %put &=six_mo_ago;
SIX_MO_AGO=21016

Beachten Sie, dass das Ergebnis eine Zahl ist, also ein SAS Datumswert, der z.B. zum Wertevergleich benötigt wird. Wenn man jedoch den formatierten Wert erhalten möchte, dann kann man ein Ausgabeformat als zweiten Parameter bei der Makrofunktion %SYSFUNC mitgeben.


%let six_mo_ago_fmt = 
  %sysfunc(
   intnx(
   month,             /* Zeitintervall */
   %sysfunc(today()), /* Ermitteln des aktuellen Datums als Startdatum */
   -6,                /* Anzahl Intervalle, 
                         negative Werte gehen in die Vergangenheit */
   same               /* Justieren des Datums innerhalb des Intervalls. 
                         "Same": Gleicher Tag innerhalb des Monats */
   ), DDMMYYP10.      /* Format mit dem die Ergebnisse formatiert werden */
  );
 %put &=six_mo_ago_fmt;

 

Ergebnis (am 16.1.2018 ausgeführt):


56          %put &=six_mo_ago_fmt;
SIX_MO_AGO_FMT=16.07.2017

 

Der berechnete Datumswert kann hervorragend dazu verwendet werden, Daten zu filtern, z.B. wenn Sie alle Daten der letzten 6 Monate selektieren wollen:


proc freq data=comm.visits (where=(date > &six_mo_ago.)) 
 noprint 
 ;
tables geo_country_code / out=country_visits_6mo;
run;

Aber was tun, wenn Sie in Ihren Daten Datetime-Werte gespeichert haben, anstatt von SAS Datumswerten? Die Funktion INTNX funktioniert auch mit Datetime-Werten und stellt dafür spezielle Datetime-Intervalle zur Verfügung. Anstatt 'month' verwenden Sie 'dtmonth'. Und statt der Funktion TODAY() verwenden Sie DATETIME().


%let six_mo_ago_dt = 
 %sysfunc(
  intnx(
   dtmonth,              /* Zeitintervall */
   %sysfunc(datetime()), /* Ermitteln des aktuellen Datums als Startdatum */
   -6,                   /* Anzahl Intervalle, 
                         negative Werte gehen in die Vergangenheit */
   same                  /* Justieren des Datums innerhalb des Intervalls. 
                         "Same": Gleicher Tag innerhalb des Monats */
   )
  );
 %put &=six_mo_ago_dt;

 

Ergebnis (am 16.1.2018 ausgeführt):


34          %put &=six_mo_ago_dt;
SIX_MO_AGO_DT=1815821358.333

 

Diesen und weitere Tipps zum Thema erhalten Sie im Kurs SAS® Programmierung 2: Datenmanagement im Data Step.