Datoer, tidspunkter og klokkeslæt

Datoer, tidspunkter og klokkeslæt i R

Det er almindeligt at arbejde med datoer og tidspunkter, når man laver dataanalyse. Datoer og tidspunkter bruges også til at studere tendenser, overlevelse og meget mere. Enhver dataanalytiker skal kunne håndtere dato- og tidsvariabler. Faktisk kan dato- og tidsvariabler håndteres som numeriske variabler, så hver dato/tid kan tildeles en numerisk værdi, som derefter kan bruges i forskellige operationer. For at tildele en numerisk værdi til en bestemt dato/tidspunkt skal en anden dato fungere som referencedato eller startpunkt. I R er denne dato sat til 1970-01-01 00:00:00 GMT. En eventuel dato/tid i fremtiden kan derefter beregnes som antallet af dage/timer/sekunder, der er forløbet siden startpunktet. Du kan naturligvis ændre referencedatoen, men det er sjældent nødvendigt.

For at arbejde med datoer og tidspunkter som numeriske variabler bruger R atomare vektorer af klassen POSIXct or POSIXt, som faktisk er doubles. Selvom disse vektortyper faktisk er numeriske værdier, kan du bruge strenge til at definere dem. Lad os begynde med at oprette to atomare vektorer med datoer:

## Vi opretter to simple tegnvektorer
birth_date <- c("1990-01-01", "1999-01-04", "2002-05-05", "2001-12-12")
death_date <- c("2005-02-02", "2009-11-14", "2018-01-01", "2011-11-09")

class(birth_date)
## [1] "character"
class(death_date)
## [1] "character"

R angiver, at begge vektorer er af typen character, som vi forventede. Lad os konvertere disse tegnvektorer til datovektorer ved hjælp af funktioner, der findes i base R (dvs. grundfunktionerne i R):

birth_date <- as.POSIXct(birth_date)
death_date <- as.POSIXct(death_date)
## Se resultat for birth_date
birth_date
## [1] "1990-01-01 CET"  "1999-01-04 CET"  "2002-05-05 CEST" "2001-12-12 CET"
## Se resultat for death_date
death_date
## [1] "2005-02-02 CET" "2009-11-14 CET" "2018-01-01 CET" "2011-11-09 CET"
## Kontrollér klasse
class(birth_date)
## [1] "POSIXct" "POSIXt"
## Kontrollér klasse
class(death_date)
## [1] "POSIXct" "POSIXt"

Vi kan beregne tidsforskellen mellem fødsel og død ved hjælp af funktionen difftime():

difftime(death_date, birth_date)
## Time differences in days
## [1] 5511.000 3967.000 5720.042 3619.000

5511.000 er tidsforskellen mellem det første element i birth_date (1990-01-01) og det første element i death_date (2005-02-02 CET). 3967.000 er tidsforskellen mellem det andet element i birth_date (1999-01-04 CET) og det andet element i death_date (2009-11-14 CET), og så videre.

R har konverteret tegnstrengene til dato-tider med klasserne POSIXct og POSIXt. Ved hjælp af POSIXct repræsenteres hver dato som antallet af sekunder, der er gået siden kl. 12:00 UTC (Universal Time Coordinated) den 1. januar 1970. Men difftime() beregner tidsforskellen i dage, hvilket er en standardindstilling. Du kan ændre dette. Hvis du f.eks. vil have tidsforskellen i sekunder, skriver man:

difftime(death_date, birth_date, units="secs")
## Time differences in secs
## [1] 476150400 342748800 494211600 312681600

Bemærk følgende kommando igen:

## Resultat for death_date
death_date
## [1] "2005-02-02 CET" "2009-11-14 CET" "2018-01-01 CET" "2011-11-09 CET"

Det fremgår af udskriften, at R har tilføjet tidszoner; CET er centraleuropæisk tid. Det var noget uventet, og faktisk kan base R-funktioner til håndtering af datoer og tidspunkter være komplicerede eller endda problematiske. Derfor skabte Garrett Grolemund, Hadley Wickham og Vitalie Spinu pakken lubridate , som gør håndteringen af datoer og tidspunkter meget enkel. Lad os installere og aktivere pakken:

## Begynd med at installere lubridate
install.packages("lubridate")

## Aktivér pakken, så dens funktioner kan bruges
library(lubridate)
## Attaching package: 'lubridate'
## The following object is masked from 'package:base':
##
##     date

Lubridate gemmer datoer som antallet af dage siden 1970-01-01. Du kan få den specifikke dato for 18000 dage efter 1970-01-01 med følgende kommando:

as_date(18000)
## [1] "2019-04-14"

18000 dage efter 1970-01-01 lander vi på datoen 2019-04-04.

Lad os gemme nogle datoværdier med lubridate. Der findes mange funktioner i lubridate til at gøre dette. Princippet for brugen af disse funktioner er følgende:

  • Angiv rækkefølgen af årstal (y), måned (m), dag (d), time (h), minut (m) og sekunder (s) i datostrengen.
  • Brug den passende funktion, hvis rækkefølge af elementerne passer til dine data.

Eksempel:

  • Vi har datoer med formatet: “1990-01-01”, hvilket betyder, at formatet er “YYYY-MM-DD”. Rækkefølgen er altså Y, M, D.
  • Den passende lubridate-funktion hedder: ymd().
  • Funktionen ymd() opretter en datovektor ud fra din streng.

Lad os afprøve det ved at oprette en dataframe med 3 personer, inklusive deres navne, fødselsdato, dato for operation og dødsdato. Alle datoer får forskellige separatorer for at teste, om funktionen ymd() kan forstå forskellige varianter af datoer:

## Opret vores vektorer (variabler)
names <- c("David", "Mohammed", "Christina")
birth <- ymd("1990-01-01", "1999-01-04", "2002-05-05")
operation <- ymd("1990.01.01", "1999.01.04", "2002.05.05")
death <- ymd("2005/02/02", "2009/11/14", "2018/01/01")

## Combine the vectors into a data frame
my_data <- data.frame(names, birth, operation, death)

## View the data frame
my_data
##       names      birth  operation      death
## 1     David 1990-01-01 1990-01-01 2005-02-02
## 2  Mohammed 1999-01-04 1999-01-04 2009-11-14
## 3 Christina 2002-05-05 2002-05-05 2018-01-01

Som du kan se i udskriften ovenfor, genkendte R de forskellige datoformer. Nu ændrer vi rækkefølgen af år, måned og dag. Når vi gør det, skal vi skifte funktion, så vi bruger en funktion, der forstår, i hvilken rækkefølge år, måned og dag kommer i strengen:

## Datostreng med rækkefølgen dag, måned og år
dmy("30-01-2000", "25-12-2001")
## [1] "2000-01-30" "2001-12-25"
## Datostreng med rækkefølgen måned, dag, år
mdy("12-25-1999", "09-29-2004")
## [1] "1999-12-25" "2004-09-29"
## Datostreng med rækkefølgen år, måned dag
ymd("20181230", "20191129")
## [1] "2018-12-30" "2019-11-29"

Igen fortolkede R datoerne korrekt. Der findes mange flere funktioner i lubridate til at håndtere datoer. Du kan downloade et cheat sheet for lubridate.

I det næste eksempel vil vi gemme en dato, der inkluderer et klokkeslæt. For at fortolke dette korrekt bruger vi en funktion, der også kan håndtere h (timer), m (minutter) og s (sekunder):

ymd_hms("2011-06-04 12:00:00")
## [1] "2011-06-04 12:00:00 UTC"

Du kan se, at R tildelte datoen tidszonen UTC. R kan håndtere omkring 600 tidszoner, for hvilke der findes information om tidszonen, sommertid og historiske kalendervariationer for området. R tildeler én tidszone pr. vektor. Du kan få en liste over alle tidszoner ved at køre følgende kommando (kun de første 20 tidszoner vises for at spare plads):

OlsonNames()
##   [1] "Africa/Abidjan"                   "Africa/Accra"
##   [3] "Africa/Addis_Ababa"               "Africa/Algiers"
##   [5] "Africa/Asmara"                    "Africa/Asmera"
##   [7] "Africa/Bamako"                    "Africa/Bangui"
##   [9] "Africa/Banjul"                    "Africa/Bissau"
##  [11] "Africa/Blantyre"                  "Africa/Brazzaville"
##  [13] "Africa/Bujumbura"                 "Africa/Cairo"
##  [15] "Africa/Casablanca"                "Africa/Ceuta"
##  [17] "Africa/Conakry"                   "Africa/Dakar"
##  [19] "Africa/Dar_es_Salaam"             "Africa/Djibouti"

Lad os oprette en datovektor, hvor vi fastsætter tidszonen til US/Stillehavsområdet:

ymd_hms("2011-06-04 12:00:00", tz="US/Pacific")
## [1] "2011-06-04 12:00:00 PDT"

Beregn tidsintervaller i R

Lad os oprette nogle data med 3 individer og deres fødsels- og dødsdatoer:

## Opret vektorer
names <- c("David", "Mohammed")
birth <- ymd("1990-01-01", "1999-01-04")
death <- ymd("2005/02/02", "2009/11/14")

## Kombinér vektorer til en dataframe
my_data <- data.frame(names, birth, death)

## Se dataframe
my_data
##      names      birth      death
## 1    David 1990-01-01 2005-02-02
## 2 Mohammed 1999-01-04 2009-11-14

Vi vil oprette en ny variabel/vektor/kolonne i vores dataframe my_data. Den nye variabel, som vi kalder dayslived, skal være tidsforskellen mellem fødsels- og dødsdato.

## Beregn tidsforskel ved subtraktion
my_data$dayslived <- my_data$death-my_data$birth

## Se data
my_data
##      names      birth      death dayslived
## 1    David 1990-01-01 2005-02-02 5511 days
## 2 Mohammed 1999-01-04 2009-11-14 3967 days

Vi kan bruge funktionen interval() til at definere et tidsinterval, som derefter kan bruges til forskellige sammenligninger. Lad os oprette en tidsintervalvariabel og kalde den time_interval:

my_data$time_interval <- interval(my_data$birth, my_data$death)
my_data

Resultatet bliver det samme, hvilket du selv kan kontrollere.

Lad os se, om David og Mohammed levede under Anden Verdenskrig.

## Definér starten på Anden Verdenskrig:
ww2start    <- ymd_hms("1939-01-01 00:00:00")
## Definér slutningen på Anden Verdenskrig:
ww2end      <- ymd_hms("1945-12-31 00:00:00")
## Definér et tidsinterval
ww2interval <- interval(ww2start, ww2end)

#Undersøg, om tidsintervallerne overlapper (dvs. om David og Mohammed levede under Anden Verdenskrig:
int_overlaps(my_data$time_interval, ww2interval)
## 1  FALSE
## 2  FALSE

Det ser ud til, at ingen af dem levede under Anden Verdenskrig, eftersom resultatet var FALSE for både David og Mohammed.

Varigheder

En varighed (duration) er tidsforskellen mellem to tidspunkter. Du beregner varigheder med lubridate ved at subtrahere datoer, som eksemplet viser:

ymd("2018-01-01") - ymd("1999-01-04")
## Time difference of 6937 days

Perioder

Du kan lægge perioder til eller trække dem fra ved hjælp af enkle funktioner på følgende måde:

ymd(20110101) + years(1)
## [1] "2012-01-01"
ymd(20110101) + months(12)
## [1] "2012-01-01"
ymd(20110101) - days(2)
## [1] "2010-12-30"
ymd(20110101) - seconds(2000)
## [1] "2010-12-31 23:26:40 UTC"