Exkurs: Datumswerte

Datumswert
R
Chunk
Tidyverse
lubridate::parse_date_time
dplyr::mutate
Author

Martin Burk

Published

September 8, 2022

Exkurs: Handling von Datumswerten.1

Datumswerte werden von Programmen und Betriebssystemen unterschiedlich kodiert. In der Regel werden Datumswerte als relative Zahl zu einem fiktiven Nullpunkt (z.B. 1. Januar 1900) gespeichert. Dies ermöglicht auch, dass innerhalb einer Software-Umgebung mit Datumswerten gerechnet werden kann.2

Der Datentransport von einer Betriebssystemumgebung zu einer anderen erfordert aber oft, dass Datumswerte in ausgeschriebener Form (also in der Darstellung mit Zeichen) kodiert werden. In der zeichenbasierten Form werden Datum (und auch Uhrzeiten) in der Regel sprachenabhängig gespeichert. Nach dem Import von Datumswerten nach R, wie wir es zuvor mit unseren Tumordokumentationsdaten gemacht haben, sind diese Datumswerte in Form von Zeichenfolgen gespeichert, deren Format abhängig von Datenquelle und Voreinstellungen ist (z.B. wird so importiert: “25-Jan-2015” oder “25.01.2015” oder auch so “2015-01-25”). Der Umgang mit solchen Werten kann durchaus anspruchsvoll sein. Berechnungen mit solchen Datumswerten sind aufwendig, nicht nur wegen der Berücksichtigung von Zeitzonen oder Schaltjahren oder -sekunden.

Auch in R existieren verschiedene Möglichkeiten, mit Datumswerten umzugehen. Eine in sich stimmige, und mir elegant erscheinende Methodik wird über das R-Programmpaket “lubridate” bereit gestellt. Lubridate gehört zum Tidyverse, und verfügt über eine umfangreiche Dokumentation3.

Wie in einem früheren Beitrag beschrieben, wurden die Daten aus einem Tumordokumentationssystem exportiert (im CSV-Format, mit Spaltennamen im SPSS-Standardformat). Diese Daten wurden wegen immer wieder beobachteter Inkompatibilitäten zwischen den Betriebssystemen (Sprach- und Ländereinstellung und davon abhängige Darstellungskonventionen, und fehlender UTF-8-Kodierung der Zeichen) zunächst nach Microsoft Excel importiert, und als CSV-Tabelle in UTF-8-Kodierung ausgegeben und dann erfolgreich nach R importiert.

Datumswerte mussten bei diesem Vorgang in der Zeichenform weitergegeben werden. Wegen der bei mir und der Tumordatenbank voreingestellten Sprache kamen die Datumswerte in der Form “DD.MM.YYYY” in R an. Sie sind dort aber als Zeichenwerte (“character”) gespeichert (eine m.E. sehr sinnvolle Voreinstellung).

Lubridate kann nun innerhalb R die Datumswerte vereinheitlichen und dabei von Zeichenwerten in Datumswerte konvertieren. Die Lubridate-Funktionen “parse date-times” werden in Abhängigkeit vom Ausgangsformat angewendet, z.B. bei unseren Daten (“DD.MM.YYYY”) die Funktion dmy().

Lubridate vereinfacht den Umgang mit Datumswerten auch über solche Konversionen hinaus: die Aufgabenstellung könnte lauten, das Alter bei Diagnosestellung (DIAALTER) aus dem Datum der Erstdiagnose (DIA_DAT) und dem Geburtsdatum (GEB_DAT) zu berechnen:
Die Berechnung der Differenz zweier Datumswerte ist nicht trivial, weil Schaltjahre und -sekunden berücksichtigt werden müssen. Lubridate berücksichtigt solche Bedingungen, und führt einen speziellen Operator “%–%” für diesen Zweck ein. Den “Pipe”-Operator “%>%” aus dem Tidyverse, der die Datentabelle von einem Berechnungsschritt zum nächsten weiterleitet, haben wir bereits verwendet. “%<>%” leistet dies ebenso, schreibt das Ergebnis aber in die Ausgangstabelle zurück.

Wir wollen ein Datum in ein neues, und als Datum verarbeitbares Format bringen. Wir wollen also die Werte einer Spalte verändern. Hierfür bietet das “Tidyverse” im Paket “dplyr” eine Funktion an, die uns ebenfalls viel Arbeit erspart: “mutate”. Mit ihr könnte auch eine neue Variable (Spalte) geschaffen werden - des würde passieren, wenn die Variable noch nicht vorhanden wäre.

Zum guten Schluss muss die Zeitendifferenz noch in Jahre umgerechnet werden, da wir das Alter bei Diagnosestellung in Jahren angeben möchten.

Jetzt sind wir präpariert, die Datenkonversionen vorzunehmen.

library(tidyverse)
library(lubridate)

# ... Testdata wurde zuvor generiert oder importiert ...

Testdata %<>% dplyr::mutate(lubridate::parse_date_time(GEB_DAT, "dmy"))
Testdata %<>% dplyr::mutate(lubridate::parse_date_time(DIA_DAT, "dmy"))

Testdata %<>% dplyr::mutate( DIAALTER = GEB_DAT %--% DIA_DAT) / years(1)

In unserer Datentabelle gibt es jetzt eine Variable namens DIAALTER, die als Differenz in Jahren aus Geburtsdatum und Diagnosedatum errechnet wurde. Für mich war anfangs erstaunlich, wie einfach es in R ist, eine ganze Tabelle oder Spalte mit einem “Einzeiler” zu erstellen. Andere Programmiersprachen benötigen in der Regel eine programmierte Schleife für dasselbe Ergebnis. Tatsächlich ließen sich die 3 Zeilen mit Testdata sogar in eine einzige zusammenpacken - sehr übersichtlich.

— | This page brought to you by https://onkostats.de . . . . . — Made with R, RStudio, Quarto, Pandoc, Mermaid, Tidyverse and GTDS … Thank you! — The R logo is copyright © R foundation, licence CC-BY-SA 4.0

Footnotes

  1. Die Uhrzeit in Worten, aus dem Eingangslogo, stammt von Akustikbasti (Lizenz CC BY-SA 3.0)↩︎

  2. Der “Nullpunkt” einer Datumszählung kann mit dem Begriff “Epoch” bezeichnet werden. In der Wikipedia findet sich eine umfangreiche und interessant geschriebene Darstellung.↩︎

  3. Referenz auf das lubridate cheatsheet↩︎