Pagina personale di:
Carlo Vecchio
appunti di C#, R, SQL Server, ASP.NET, algoritmi, numeri
Vai ai contenuti

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


© 2022 Carlo Vecchio
Torna ai contenuti