R - Date e Ore in R
R
Date e Ore in R
Generalità sulle date
- Le date sono memorizzate in un oggetto di tipo Date.
- Il codice seguente mostra come estrarre la data attuale - con Sys.Date() - e come sommare ad una variabile di tipo Date, un numero di giorni.
# Data attuale.
data.attuale <- Sys.Date()
print(data.attuale)
[1] "2020-04-11"
class(data.attuale)
[1] "Date"
print(data.attuale + 42)
[1] "2020-05-23"
- Il codice seguente mostra come assegnare ad un oggetto una data qualsiasi con la funzione as.Date() e l'utilizzo della funzione weekdays() per ricavare il giorno della settimana.
# Impostare una data qualsiasi.
data.generica <- as.Date("2019-08-20")
print(data.generica)
[1] "2019-08-20"
weekdays(data.generica)
[1] "martedì"
- La funzione as.Date() funziona senza altri parametri se la data è nel formato anno-mese-giorno, con separatore il trattino "-" o la barra "/".
- Nel caso che la data sia in un altro formato, utilizzare il parametro opzionale format. In esso viene descritto il formato della data utilizzando i seguenti segnaposto.
- %d: giorno del mese (decimale)
- %m: mese (decimale)
- %b: mese (stringa abbreviata)
- %B: mese (stringa lunga)
- %y: anno (2 cifre)
- %Y: anno (4 cifre)
- Ecco alcuni esempi, tutti con la stessa data in formati diversi.
data.generica <- as.Date("2019-08-20")
print(data.generica)
[1] "2019-08-20"
data.generica <- as.Date("2019/08/20")
print(data.generica)
[1] "2019-08-20"
data.generica <- as.Date("20-08-2019", format = '%d-%m-%Y')
print(data.generica)
[1] "2019-08-20"
data.generica <- as.Date("20 08 19", format = '%d %m %y')
print(data.generica)
[1] "2019-08-20"
data.generica <- as.Date("20 Agosto 2019", format = '%d %B %Y')
print(data.generica)
[1] "2019-08-20"
- Il codice seguente mostra come creare vettori di date.
- Nel primo esempio il vettore contiere date consecutive.
- Nel secondo esempio il vettore contiene date con un salto di 7 giorni.
# Sequenze di date.
x <- 0:10
data.iniziale <- as.Date("2020-01-01")
print(data.iniziale + 0:10)
[1] "2020-01-01" "2020-01-02" "2020-01-03" "2020-01-04" "2020-01-05" "2020-01-06"
[7] "2020-01-07" "2020-01-08" "2020-01-09" "2020-01-10" "2020-01-11"
seq(Sys.Date(), by = 7, length.out = 10)
[1] "2020-04-11" "2020-04-18" "2020-04-25" "2020-05-02" "2020-05-09" "2020-05-16"
[7] "2020-05-23" "2020-05-30" "2020-06-06" "2020-06-13"
Generalità sulle ore
- Le ore sono memorizzate in un oggetto di tipo POSIXct che - attenzione - contiene sia la data che l'ora.
- Il formato standard è anno-mese-giorno separati con il trattino (-) o la barra (/), seguiti da uno spazio, seguiti da ore-minuti-secondi separati dai due punti (:).
- Il codice seguente mostra come estrarre la data-ora attuale - con Sys.time(). Il tipo di oggetto è POSIXct.
# Ora attuale.
ora.attuale <- Sys.time()
print(ora.attuale)
[1] "2020-04-11 18:38:54 CEST"
class(ora.attuale)
[1] "POSIXct" "POSIXt"
- Per estrarre il numero di secondi passati dal 1° gennaio 1970 di un oggetto data-ora, si veda il codice successivo.
# Numero di secondi passati dal 1 gennaio 1970.
sec <- unclass(Sys.time())
print(sec)
[1] 1586635559
- Per estrarre tutte le informazioni dei un oggetto data-ora, si veda il codice seguente.
# Estrazione di tutte le variabili.
now <- as.POSIXlt(Sys.time())
print(now)
[1] "2020-04-11 22:17:01 CEST"
print(unlist(unclass(now)))
sec min hour mday
"1.17713499069214" "17" "22" "11"
mon year wday yday
"3" "120" "6" "101"
isdst zone gmtoff
"1" "CEST" "7200"
print(now$sec) # Secondi.
[1] 1.177135
print(now$min) # Minuti.
[1] 17
print(now$hour) # Ore.
[1] 22
print(now$mday) # Giorno del mese.
[1] 11
print(now$mon) # Mese (sommare 1 perché è a base 0).
[1] 3
print(now$year) # Anno (sommare 1900).
[1] 120
print(now$wday) # Giorno della settimana (0 = domenica).
[1] 6
print(now$yday) # Giorno progressivo dell'anno (a base 0).
[1] 101
print(now$isdst) # Ora legale (>0 = sì; 0 = no; <0 = sconosciuto).
[1] 1
print(now$zone) # Fuso orario.
[1] "CEST"
print(now$gmtoff) # Offset in secondi rispetto all'ora GMT.
[1] 7200
- È possibile leggere comunque una data-ora anche se il formato non è quello standard.
- Il parametro format permette infatti di indicare il formato utilizzato durante la lettura.
- Ecco un esempio.
data.ora <- as.POSIXct("2020-01-02 10:11:12")
print(data.ora)
[1] "2020-01-02 10:11:12 CET"
data.ora <- as.POSIXct("2020-01-02 10.11.12", format = '%Y-%m-%d %H.%M.%S')
print(data.ora)
[1] "2020-01-02 10:11:12 CET"
Il pacchetto Lubridate
- La gestione delle date e delle ore con le classi standard fornite da R, può essere frustrante.
- Il pacchetto Lubridate viene incontro con una serie di classi e di funzioni molto intuitive.
- Per accedervi, occorre installare il pacchetto e caricarlo con le istruzioni seguenti.
install.packages("lubridate")
library(lubridate)
- La gestione delle date è facilitata da una serie di funzioni che permettono di inserire il giorno, il mese e l'anno con qualsiasi separatore e in qualsiasi ordine.
- Gli esempi seguenti mostrano la creazione di un oggetto Date con vari separatori, utilizzando la sola funzione ymd().
# Utilizzo di qualsiasi separatore.
data1 <- ymd('2000-08-20')
print(data1)
[1] "2000-08-20"
data1 <- ymd('2000/08/20')
print(data1)
[1] "2000-08-20"
data1 <- ymd('2000 08 20')
print(data1)
[1] "2000-08-20"
data1 <- ymd('20000820')
print(data1)
[1] "2000-08-20"
- Gli esempi seguenti mostrano la creazione di un oggetto Date con un ordinamento diverso da quello standard. Sono disponibili tutte le sei combinazioni: ymd(), ydm(), myd(), mdy(), dym(), dmy().
# Anno, mese e giorno in qualsiasi ordine.
data1 <- dmy('20-08-2000')
print(data1)
[1] "2000-08-20"
data1 <- mdy('08-20-2000')
print(data1)
[1] "2000-08-20"
- Gli esempi seguenti mostrano la creazione di un oggetto data-ora (è un oggetto POSIXct). Come si vede dagli esempi si possono indicare solo le ore, oppure le ore e i minuti, oppure le ore, i minuti e i secondi. Anche sul separatore tra le ore, i minuti e i secondi, c'è una certa libertà di utilizzo.
# Anno, mese, giorno, ore, minuti e secondi.
data1 <- ymd_h('2000-08-20 19')
print(data1)
[1] "2000-08-20 19:00:00 UTC"
data1 <- ymd_hm('2000-08-20 19:20')
print(data1)
[1] "2000-08-20 19:20:00 UTC"
data1 <- ymd_hms('2000-08-20 19:20:21')
print(data1)
[1] "2000-08-20 19:20:21 UTC"
data1 <- ymd_hms('2000-08-20 19.20.21')
print(data1)
[1] "2000-08-20 19:20:21 UTC"
data1 <- ymd_hms('2000-08-20 192021')
print(data1)
[1] "2000-08-20 19:20:21 UTC"
- Dato un oggetto data-ora è possibile aggiornarne il valore di una qualsiasi proprietà: l'anno, il mese, ecc. Per fare questo utilizzare la funzione update().
# Aggiornare una data-ora.
data1 <- ymd_hms('2000-08-20 19.20.21')
print(data1)
[1] "2000-08-20 19:20:21 UTC"
data1 = update(data1, year = 2001, month = 09, day = 21, hour = 20, minutes = 21, seconds = 22)
print(data1)
[1] "2001-09-21 20:21:22 UTC"
- Dato un oggetto data-ora è possibile sommare o sottrarre un periodo (o intervallo) di tempo.
# Sommare a una data-ora un periodo di tempo.
data1 <- ymd_hms('2000-08-20 19.20.21')
print(data1)
[1] "2000-08-20 19:20:21 UTC"
data2 <- data1 + years(1) + months(1) + days(1) + hours(1) + minutes(1) + seconds(1)
print(data2)
[1] "2001-09-21 20:21:22 UTC"
- Dati due oggetti data-ora, se ne può calcolare la differenza che è un oggetto di tipo Period.
# Differenza tra due data-ora.
data1 <- ymd_hms('2000-08-20 19.20.21')
print(data1)
[1] "2000-08-20 19:20:21 UTC"
data2 <- ymd_hms('2001-08-21 20.21.22')
print(data2)
[1] "2001-08-21 20:21:22 UTC"
diff <- as.period(data2 - data1)
print(diff)
[1] "366d 1H 1M 1S"
diff.sec <- period_to_seconds(diff)
print(diff.sec)
[1] 31626061
Periodi in millisecondi
- Nei processi si acquisizione dati, si utilizzano unità di tempo inferiori al secondo. Generalmente l'unità di tempo è il millisecondo.
- Dati due istanti di tempo, può essere utile calcolarne la differenza in millisecondi.
- Gli istanti di tempo sono due oggetti POSIXct, mentre la differenza la vogliamo calcolare come valore numerico.
- Il codice sotto riportato utilizza il package Lubridate. Come si vede nell'esempio, i due istanti differiscono di 1 ora, 1 minuto, 1 secondo e 333 millesimi.
# Gestione di millisecondi.
data1 <- ymd_hms('2000-08-20 19:20:21.123')
print(data1)
[1] "2000-08-20 19:20:21 UTC"
data2 <- ymd_hms('2000-08-20 20:21:22.456')
print(data2)
[1] "2000-08-20 20:21:22 UTC"
diff <- as.period(data2 - data1)
print(diff)
[1] "1H 1M 1.33299994468689S"
millisecondi <- as.numeric(round(seconds(diff) * 1e3, 0))
print(millisecondi)
[1] 3661333