15  Veiksmai su datos ir laiko duomenimis

Įterpti lubridate paketą

Dirbant su datos ir laiko duomenimis, paprastai reikia atlikti tokius veiksmus:

15.1 Sekų generavimas ir skaidymas

Jei laiko momentas užrašytas kaip POSIXlt klasės objektas, kai kurias datos ir laiko komponentes galima gauti be jokių papildomų funkcijų, kadangi tokiu būdu užrašytas laiko momentas yra įvairių laiko ir datos komponenčių sąrašas. Pvz., nustatysime, kelinta savaitės, mėnesio ir metų diena yra ši diena.

Kodas
t <- as.POSIXlt(Sys.time())
t
#> [1] "2025-11-26 20:37:56 EET"

t$wday
#> [1] 3
t$mday
#> [1] 26
t$yday
#> [1] 329

Savaitės dienos, mėnesio pavadinimo ir metų ketvirčio nustatymui bendru atveju gali būti naudojamos šios funkcijos: weekdays(), months(), quarters(). Visų funkcijų argumentai vienodi.

Argumentas Reikšmė
x data arba laikas,
abbreviate loginis, nurodo, pavadinimas turi būti sutrumpintas.

Pavyzdžiui, žinomos kelių artimiausių pilnų Saulės užtemimų datos. Nustatysime, kurią savaitės dieną vyko Saulės užtemimai nurodytomis datomis.

Kodas
data <- c("2016-03-08", "2017-08-21", "2019-07-02", "2020-12-14", "2021-12-04")
d <- as.Date(data)
weekdays(d)
#> [1] "antradienis" "pirmadienis" "antradienis" "pirmadienis" "šeštadienis"

Kadangi datos ir laiko kintamieji, nepriklausomai nuo jų formato, saugomi kaip skaičiai, keletas standartinių funkcijų turi metodus datos ir laiko objektams:

Datoms Laikui
trunc.Date trunc.POSIXt
round.Date round.POSIXt
seq.Date seq.POSIXt
cut.Date cut.POSIXt
hist.Date hist.POSIXt
axis.Date axis.POSIXt

Tai reiškia, kad su datomis ir laiku galima elgtis kaip su įprastais skaičiais: juos apvalinti iki norimo tikslumo, generuoti laiko momentų sekas arba turimus laiko momentus grupuoti į intervalus.

Jeigu duotą laiko momentą reikia užrašyti dienų, valandų, minučių ar sekundžių tikslumu, naudojama funkcija trunc. Jeigu laiko momentą reikia suapvalinti iki artimiausio laiko momento dienų, valandų, minučių arba sekundžių tikslumu, tai naudojama funkcija round. Abiejų funkcijų parametrai vienodi:

Argumentas Reikšmė
x laiko momentas
units laiko apvalinimo vienetai, secs, mins, hours arba days

Pavyzdžiui, duotas laiko momentas sekundės tūkstantųjų tikslumu. Užrašysime jį dienų, valandų, minučių ir sekundžių tikslumu. Vienu atveju naudosime funkciją trunc(), kitu – funkciją round().

Kodas
t <- as.POSIXct("2015-11-22 18:39:12.683", format = "%Y-%m-%d %H:%M:%OS")
t
#> [1] "2015-11-22 18:39:12 EET"

format(t, format = "%H:%M:%OS3")
#> [1] "18:39:12.683"

trunc(t, "day")
#> [1] "2015-11-22 EET"
round(t, "day")
#> [1] "2015-11-23 EET"

trunc(t, "hours")
#> [1] "2015-11-22 18:00:00 EET"
round(t, "hours")
#> [1] "2015-11-22 19:00:00 EET"

trunc(t, "mins")
#> [1] "2015-11-22 18:39:00 EET"
round(t, "mins")
#> [1] "2015-11-22 18:39:00 EET"

trunc(t, "secs")
#> [1] "2015-11-22 18:39:12 EET"
round(t, "secs")
#> [1] "2015-11-22 18:39:13 EET"

Datų ir laiko momentų sekos generavimui naudojama funkcija seq(), t. y. tapati funkcija, kuri skirta ir realiųjų skaičių sekų generavimui. Ši standartinė funkcija turi atskirus metodus Date ir POSIXt klasės objektams.

seq.Date()

Parametrui from priskiriame Date klasės reikšmę. Parametras to neprivalomas, jeigu per parametrus length.out arba along.with nurodome bendrą sekos elementų skaičių. Parametrui by reikšmę galima priskirti net keliais skirtingais būdais, kadangi sekos kitimo žingsnis, intervalas tarp dviejų sekos elementų gali būti:

  • skaičius, kuris nurodo dienų skaičių;

  • difftime klasės objektas;

  • žodinis laiko intervalas: "day", "week", "month", "quarter", "year";

  • kartotinis laiko intervalas: "7 days", "2 months", "-1 years" ir pan.

Tarkime, kad sekos pradžia ir pabaiga yra pirma ir paskutinė 2025 metų dienos. Sudarysime keletą skirtingų sekų su įvairaus dydžio tarpais tarp gretimų datų.

Kodas
pr <- as.Date("2025-01-01")
pb <- as.Date("2025-12-31")

Sugeneruosime seką, kurią sudaro visos sausio mėnesio dienos.

Kodas
seq(pr, by = "day", length.out = 31)      
#>  [1] "2025-01-01" "2025-01-02" "2025-01-03" "2025-01-04" "2025-01-05"
#>  [6] "2025-01-06" "2025-01-07" "2025-01-08" "2025-01-09" "2025-01-10"
#> [11] "2025-01-11" "2025-01-12" "2025-01-13" "2025-01-14" "2025-01-15"
#> [16] "2025-01-16" "2025-01-17" "2025-01-18" "2025-01-19" "2025-01-20"
#> [21] "2025-01-21" "2025-01-22" "2025-01-23" "2025-01-24" "2025-01-25"
#> [26] "2025-01-26" "2025-01-27" "2025-01-28" "2025-01-29" "2025-01-30"
#> [31] "2025-01-31"

Sudarome seką, kurioje į praeitį atidedame penkias datas kas du metus.

Kodas
seq(pr, by = "-2 years", length.out = 5)
#> [1] "2025-01-01" "2023-01-01" "2021-01-01" "2019-01-01" "2017-01-01"

Vienerių metų intervalą suskirstome 4 savaičių ilgio laiko intervalais.

Kodas
seq(pr, pb, by = "4 weeks")
#>  [1] "2025-01-01" "2025-01-29" "2025-02-26" "2025-03-26" "2025-04-23"
#>  [6] "2025-05-21" "2025-06-18" "2025-07-16" "2025-08-13" "2025-09-10"
#> [11] "2025-10-08" "2025-11-05" "2025-12-03" "2025-12-31"

seq.POSIXt()

Jeigu funkcija seq() naudojama laiko sekoms generuoti, tada parametrams from, to nurodome POSIXt laiko momentą, o parametrui by galima nurodyti šias reikšmes:

  • skaičių, kuris reiškia sekundžių skaičių;

  • difftime klasės objektą;

  • intervalą: “sec”, “min”, “hour”, “day”, “week”, “month”, “quarter”, “year”;

  • kartotinį laiko intervalą: “15 secs”, “2 hour”, “-1 years” ir pan.

Pavyzdžiui, vienos valandos ilgio intervalą reikia padalinti į mažesnius laiko intervalus po 90 sekundžių. Pradinis momentas 08:00:00, galutinis – 09:00:00.

Kodas
pr <- as.POSIXlt("2015-01-01 08:00:00")
pb <- as.POSIXlt("2015-01-01 09:00:00")

seq(pr, pb, by = "90 secs")
#>  [1] "2015-01-01 08:00:00 EET" "2015-01-01 08:01:30 EET"
#>  [3] "2015-01-01 08:03:00 EET" "2015-01-01 08:04:30 EET"
#>  [5] "2015-01-01 08:06:00 EET" "2015-01-01 08:07:30 EET"
#>  [7] "2015-01-01 08:09:00 EET" "2015-01-01 08:10:30 EET"
#>  [9] "2015-01-01 08:12:00 EET" "2015-01-01 08:13:30 EET"
#> [11] "2015-01-01 08:15:00 EET" "2015-01-01 08:16:30 EET"
#> [13] "2015-01-01 08:18:00 EET" "2015-01-01 08:19:30 EET"
#> [15] "2015-01-01 08:21:00 EET" "2015-01-01 08:22:30 EET"
#> [17] "2015-01-01 08:24:00 EET" "2015-01-01 08:25:30 EET"
#> [19] "2015-01-01 08:27:00 EET" "2015-01-01 08:28:30 EET"
#> [21] "2015-01-01 08:30:00 EET" "2015-01-01 08:31:30 EET"
#> [23] "2015-01-01 08:33:00 EET" "2015-01-01 08:34:30 EET"
#> [25] "2015-01-01 08:36:00 EET" "2015-01-01 08:37:30 EET"
#> [27] "2015-01-01 08:39:00 EET" "2015-01-01 08:40:30 EET"
#> [29] "2015-01-01 08:42:00 EET" "2015-01-01 08:43:30 EET"
#> [31] "2015-01-01 08:45:00 EET" "2015-01-01 08:46:30 EET"
#> [33] "2015-01-01 08:48:00 EET" "2015-01-01 08:49:30 EET"
#> [35] "2015-01-01 08:51:00 EET" "2015-01-01 08:52:30 EET"
#> [37] "2015-01-01 08:54:00 EET" "2015-01-01 08:55:30 EET"
#> [39] "2015-01-01 08:57:00 EET" "2015-01-01 08:58:30 EET"
#> [41] "2015-01-01 09:00:00 EET"

Tarkime, kad reikalinga seka iš 10 laiko momentų kas 45 minutes.

Kodas
seq(pr, by = "45 mins", length.out = 10)
#>  [1] "2015-01-01 08:00:00 EET" "2015-01-01 08:45:00 EET"
#>  [3] "2015-01-01 09:30:00 EET" "2015-01-01 10:15:00 EET"
#>  [5] "2015-01-01 11:00:00 EET" "2015-01-01 11:45:00 EET"
#>  [7] "2015-01-01 12:30:00 EET" "2015-01-01 13:15:00 EET"
#>  [9] "2015-01-01 14:00:00 EET" "2015-01-01 14:45:00 EET"

cut.Date() ir cut.POSIXt()

Datų ir laiko momentų grupavimui naudojama funkcija cut() - ji turi metodus Date ir POSIXt klasės objektams. Pagrindiniai šios funkcijos parametrai yra tokie:

Argumentas Reikšmė
x datų arba laiko momentų vektorius
breaks padalijimo taškų vektorius arba norimas intervalų skaičius
labels NULL, intervalų pavadinimų vektorius
right FALSE, nurodo ar intervalo galas uždaras iš dešinės

Grupuojant laiko intervalus parametrui breaks galima nurodyti tokias reikšmes: “sec”, “min”, “hour”, “day”, “DSTday”, “week”, “month”, “quarter” arba “year”.

Pavyzdžiui, vienos paros bėgyje atidėsime 100 atsitiktinių laiko momentų, tada juos suskirstysime į intervalus po 6 valandas bei apskaičiuosime laiko momentų dažnius kiekviename tokiame intervale.

Kodas
# generuojami atsitiktiniai laiko momentai
t <- ISOdatetime(2015, 11, 23, 0, 0, 0) + 24*3600*runif(100)
t
#>   [1] "2015-11-23 16:19:37 EET" "2015-11-23 11:05:23 EET"
#>   [3] "2015-11-23 06:09:08 EET" "2015-11-23 20:12:26 EET"
#>   [5] "2015-11-23 00:10:34 EET" "2015-11-23 20:32:51 EET"
#>   [7] "2015-11-23 05:22:15 EET" "2015-11-23 01:42:35 EET"
#>   [9] "2015-11-23 16:34:06 EET" "2015-11-23 16:52:05 EET"
#>  [11] "2015-11-23 20:14:36 EET" "2015-11-23 02:30:33 EET"
#>  [13] "2015-11-23 04:03:21 EET" "2015-11-23 17:53:21 EET"
#>  [15] "2015-11-23 17:15:02 EET" "2015-11-23 18:43:30 EET"
#>  [17] "2015-11-23 12:03:08 EET" "2015-11-23 02:35:01 EET"
#>  [19] "2015-11-23 03:47:05 EET" "2015-11-23 23:31:34 EET"
#>  [21] "2015-11-23 08:55:18 EET" "2015-11-23 23:24:01 EET"
#>  [23] "2015-11-23 16:53:56 EET" "2015-11-23 19:25:40 EET"
#>  [25] "2015-11-23 18:48:31 EET" "2015-11-23 20:52:02 EET"
#>  [27] "2015-11-23 05:59:16 EET" "2015-11-23 04:56:31 EET"
#>  [29] "2015-11-23 12:55:49 EET" "2015-11-23 03:43:26 EET"
#>  [31] "2015-11-23 07:14:13 EET" "2015-11-23 04:22:58 EET"
#>  [33] "2015-11-23 00:21:42 EET" "2015-11-23 05:35:28 EET"
#>  [35] "2015-11-23 09:00:12 EET" "2015-11-23 23:25:21 EET"
#>  [37] "2015-11-23 15:19:22 EET" "2015-11-23 06:04:42 EET"
#>  [39] "2015-11-23 03:07:12 EET" "2015-11-23 12:08:06 EET"
#>  [41] "2015-11-23 04:43:25 EET" "2015-11-23 17:00:19 EET"
#>  [43] "2015-11-23 06:56:19 EET" "2015-11-23 23:16:03 EET"
#>  [45] "2015-11-23 02:29:19 EET" "2015-11-23 13:22:06 EET"
#>  [47] "2015-11-23 21:17:03 EET" "2015-11-23 11:59:57 EET"
#>  [49] "2015-11-23 21:31:48 EET" "2015-11-23 11:49:01 EET"
#>  [51] "2015-11-23 15:36:20 EET" "2015-11-23 06:14:00 EET"
#>  [53] "2015-11-23 04:56:59 EET" "2015-11-23 16:26:52 EET"
#>  [55] "2015-11-23 06:50:02 EET" "2015-11-23 07:56:58 EET"
#>  [57] "2015-11-23 22:09:16 EET" "2015-11-23 23:00:55 EET"
#>  [59] "2015-11-23 13:45:43 EET" "2015-11-23 14:47:46 EET"
#>  [61] "2015-11-23 07:41:09 EET" "2015-11-23 14:22:55 EET"
#>  [63] "2015-11-23 04:40:10 EET" "2015-11-23 20:05:30 EET"
#>  [65] "2015-11-23 13:27:38 EET" "2015-11-23 09:22:15 EET"
#>  [67] "2015-11-23 00:17:28 EET" "2015-11-23 11:53:02 EET"
#>  [69] "2015-11-23 03:22:17 EET" "2015-11-23 13:00:02 EET"
#>  [71] "2015-11-23 08:20:42 EET" "2015-11-23 12:00:24 EET"
#>  [73] "2015-11-23 15:25:29 EET" "2015-11-23 09:33:19 EET"
#>  [75] "2015-11-23 00:49:58 EET" "2015-11-23 09:10:44 EET"
#>  [77] "2015-11-23 01:42:27 EET" "2015-11-23 04:44:14 EET"
#>  [79] "2015-11-23 17:03:28 EET" "2015-11-23 04:06:25 EET"
#>  [81] "2015-11-23 01:51:58 EET" "2015-11-23 10:50:26 EET"
#>  [83] "2015-11-23 20:09:00 EET" "2015-11-23 16:02:00 EET"
#>  [85] "2015-11-23 12:04:41 EET" "2015-11-23 20:34:46 EET"
#>  [87] "2015-11-23 02:47:43 EET" "2015-11-23 21:52:52 EET"
#>  [89] "2015-11-23 21:26:52 EET" "2015-11-23 18:30:21 EET"
#>  [91] "2015-11-23 16:06:17 EET" "2015-11-23 13:05:16 EET"
#>  [93] "2015-11-23 06:09:49 EET" "2015-11-23 20:06:03 EET"
#>  [95] "2015-11-23 08:56:44 EET" "2015-11-23 07:50:43 EET"
#>  [97] "2015-11-23 00:50:26 EET" "2015-11-23 23:20:00 EET"
#>  [99] "2015-11-23 12:26:19 EET" "2015-11-23 20:35:02 EET"

# grafinis laiko momentu atvaizdavimas
windows(9, 4)
plot(t, rep(0, 100), type = "n", xlab = "laikas", ylab = "", yaxt = "n")
rug(t)

# skaidymas į 6 intervalus
intervalai <- cut(t, breaks = "6 hour")
intervalai
#>   [1] 2015-11-23 12:00:00 2015-11-23 06:00:00 2015-11-23 06:00:00
#>   [4] 2015-11-23 18:00:00 2015-11-23          2015-11-23 18:00:00
#>   [7] 2015-11-23          2015-11-23          2015-11-23 12:00:00
#>  [10] 2015-11-23 12:00:00 2015-11-23 18:00:00 2015-11-23         
#>  [13] 2015-11-23          2015-11-23 12:00:00 2015-11-23 12:00:00
#>  [16] 2015-11-23 18:00:00 2015-11-23 12:00:00 2015-11-23         
#>  [19] 2015-11-23          2015-11-23 18:00:00 2015-11-23 06:00:00
#>  [22] 2015-11-23 18:00:00 2015-11-23 12:00:00 2015-11-23 18:00:00
#>  [25] 2015-11-23 18:00:00 2015-11-23 18:00:00 2015-11-23         
#>  [28] 2015-11-23          2015-11-23 12:00:00 2015-11-23         
#>  [31] 2015-11-23 06:00:00 2015-11-23          2015-11-23         
#>  [34] 2015-11-23          2015-11-23 06:00:00 2015-11-23 18:00:00
#>  [37] 2015-11-23 12:00:00 2015-11-23 06:00:00 2015-11-23         
#>  [40] 2015-11-23 12:00:00 2015-11-23          2015-11-23 12:00:00
#>  [43] 2015-11-23 06:00:00 2015-11-23 18:00:00 2015-11-23         
#>  [46] 2015-11-23 12:00:00 2015-11-23 18:00:00 2015-11-23 06:00:00
#>  [49] 2015-11-23 18:00:00 2015-11-23 06:00:00 2015-11-23 12:00:00
#>  [52] 2015-11-23 06:00:00 2015-11-23          2015-11-23 12:00:00
#>  [55] 2015-11-23 06:00:00 2015-11-23 06:00:00 2015-11-23 18:00:00
#>  [58] 2015-11-23 18:00:00 2015-11-23 12:00:00 2015-11-23 12:00:00
#>  [61] 2015-11-23 06:00:00 2015-11-23 12:00:00 2015-11-23         
#>  [64] 2015-11-23 18:00:00 2015-11-23 12:00:00 2015-11-23 06:00:00
#>  [67] 2015-11-23          2015-11-23 06:00:00 2015-11-23         
#>  [70] 2015-11-23 12:00:00 2015-11-23 06:00:00 2015-11-23 12:00:00
#>  [73] 2015-11-23 12:00:00 2015-11-23 06:00:00 2015-11-23         
#>  [76] 2015-11-23 06:00:00 2015-11-23          2015-11-23         
#>  [79] 2015-11-23 12:00:00 2015-11-23          2015-11-23         
#>  [82] 2015-11-23 06:00:00 2015-11-23 18:00:00 2015-11-23 12:00:00
#>  [85] 2015-11-23 12:00:00 2015-11-23 18:00:00 2015-11-23         
#>  [88] 2015-11-23 18:00:00 2015-11-23 18:00:00 2015-11-23 18:00:00
#>  [91] 2015-11-23 12:00:00 2015-11-23 12:00:00 2015-11-23 06:00:00
#>  [94] 2015-11-23 18:00:00 2015-11-23 06:00:00 2015-11-23 06:00:00
#>  [97] 2015-11-23          2015-11-23 18:00:00 2015-11-23 12:00:00
#> [100] 2015-11-23 18:00:00
#> 4 Levels: 2015-11-23 2015-11-23 06:00:00 ... 2015-11-23 18:00:00

# gautų intervalų dažnių lentelė
table(intervalai)
#> intervalai
#>          2015-11-23 2015-11-23 06:00:00 2015-11-23 12:00:00 2015-11-23 18:00:00 
#>                  27                  22                  27                  24

Pavyzdžiui, visą parą suskirstysime į du nevienodo ilgio intervalus: nuo 00:00 iki 05:59 ir nuo 06:00 iki 23:59. Tokiu atveju parametrui breaks nurodome tris laiko momentus POSIX formatu.

Kodas
p <- c("2015-11-23 00:00:00", "2015-11-23 06:00:00", "2015-11-23 23:59:59")
p <- strptime(p, format = "%Y-%m-%d %H:%M:%S")

intervalai <- cut(t, breaks = p, labels = c("naktis", "diena"))
intervalai
#>   [1] diena  diena  diena  diena  naktis diena  naktis naktis diena  diena 
#>  [11] diena  naktis naktis diena  diena  diena  diena  naktis naktis diena 
#>  [21] diena  diena  diena  diena  diena  diena  naktis naktis diena  naktis
#>  [31] diena  naktis naktis naktis diena  diena  diena  diena  naktis diena 
#>  [41] naktis diena  diena  diena  naktis diena  diena  diena  diena  diena 
#>  [51] diena  diena  naktis diena  diena  diena  diena  diena  diena  diena 
#>  [61] diena  diena  naktis diena  diena  diena  naktis diena  naktis diena 
#>  [71] diena  diena  diena  diena  naktis diena  naktis naktis diena  naktis
#>  [81] naktis diena  diena  diena  diena  diena  naktis diena  diena  diena 
#>  [91] diena  diena  diena  diena  diena  diena  naktis diena  diena  diena 
#> Levels: naktis diena

table(intervalai)
#> intervalai
#> naktis  diena 
#>     27     73

Analogiškai į intervalus suskirstomos ir datos. Pvz., dviejų mėnesių intervale (pradedant nuo 2025-11-23) sugeneruosime 20 atsitiktinių datų ir suskirstysime jas į dviejų savaičių ilgio intervalus.

Kodas
d <- as.Date("2025-11-23") + 2*30*runif(20)
d
#>  [1] "2025-12-31" "2026-01-09" "2026-01-14" "2026-01-02" "2026-01-08"
#>  [6] "2025-12-23" "2025-12-11" "2026-01-11" "2025-12-03" "2026-01-15"
#> [11] "2025-12-11" "2025-11-27" "2026-01-19" "2025-12-19" "2026-01-17"
#> [16] "2025-12-21" "2025-11-24" "2025-11-29" "2026-01-14" "2025-12-27"

intervalai <- cut(d, breaks = "2 weeks")
intervalai
#>  [1] 2025-12-22 2026-01-05 2026-01-05 2025-12-22 2026-01-05 2025-12-22
#>  [7] 2025-12-08 2026-01-05 2025-11-24 2026-01-05 2025-12-08 2025-11-24
#> [13] 2026-01-19 2025-12-08 2026-01-05 2025-12-08 2025-11-24 2025-11-24
#> [19] 2026-01-05 2025-12-22
#> Levels: 2025-11-24 2025-12-08 2025-12-22 2026-01-05 2026-01-19

table(intervalai)
#> intervalai
#> 2025-11-24 2025-12-08 2025-12-22 2026-01-05 2026-01-19 
#>          4          4          4          7          1

15.2 Skirtumas tarp dviejų laiko momentų

Turint datą ar laiko momentą, prie jo galima pridėti tam tikrą laiko intervalą. Prie datos pridedamas skaičius nurodo dienų skaičių, prie POSIX laiko - nurodo sekundžių skaičių. Pavyzdžiui, prie šios dienos datos pridėsime šimtą dienų ir gausime naują datą.

Kodas
# Sys.Date() yra Date klasės objektas 
Sys.Date() + 100
#> [1] "2026-03-06"

Pavyzdžiui, prie laiko momento pridėsime 120 sekundžių ir tokiu būdu gausime 2 minutėmis vėlesnį laiko momentą.

Kodas
# POSIXt klasės objektai
ISOdatetime(2015, 11, 25, 21, 14, 00) + 120
#> [1] "2015-11-25 21:16:00 EET"

as.POSIXlt("2015-11-25 21:14:00")     + 120
#> [1] "2015-11-25 21:16:00 EET"

Turint dvi datas arba du laiko momentus, galima apskaičiuoti skirtumą tarp jų. Pvz., nustatysime koks laiko skirtumas tarp atominės bombos sprogimų Japonijos miestuose Hiroshima ir Nagasaki.

Kodas
Hiroshima <- as.POSIXlt("1945-08-06 08:15:00", tz = "Japan")
Nagasakis <- as.POSIXlt("1945-08-09 11:02:00", tz = "Japan")

Nagasakis - Hiroshima
#> Time difference of 3.115972 days

Pvz., apskaičiuosime, kiek laiko praėjo nuo Hiroshima atominės bombos sprogimo.

Kodas
Sys.time() - Hiroshima
#> Time difference of 29332.81 days

Gautas laiko skirtumas yra difftime klasės objektas. Skirtumą galima pridėti arba atimti iš datos arba laiko momento.

Kodas
d <- Nagasakis - Hiroshima
d
#> Time difference of 3.115972 days

Hiroshima + d
#> [1] "1945-08-09 11:02:00 JST"
Hiroshima + d == Nagasakis
#> [1] TRUE

difftime() ir diff()

Jeigu reikia apskaičiuoti skirtumą tarp dviejų datų arba dviejų laiko momentų, galima naudoti funkciją difftime(). Tada galima nurodyti, kokiais vienetais turi būti išreikštas gautas laiko skirtumas.

Argumentas Reikšmė
time1 pradinis laiko momentas
time2 galutinis laiko momentas
tz laiko zona
units laiko vienetai: “auto”, “secs”, “mins”, “hours”, “days”, “weeks”

Jeigu parametrui units priskiriama reikšmė “auto”, tai laiko skirtumas rodomas didžiausiais laiko vienetais. Galima pastebėti, kad tarp laiko vienetų mėnesių nėra. Taip yra todėl, kad skirtingus mėnesius sudaro skirtingas dienų skaičius.

Kodas
difftime(Nagasakis, Hiroshima, units = "days")
#> Time difference of 3.115972 days
difftime(Nagasakis, Hiroshima, units = "hours")
#> Time difference of 74.78333 hours

Jeigu turime datų arba laiko momentų vektorių, skirtumus tarp gretimų reikšmių galime nustatyti naudojant standartinę funkciją diff(). Pavyzdžiui, taip gausime dienomis išreikštus laiko skirtumus tarp didžiausių LDK mūšių datų.

Kodas
#          Saulės        Durbės        Žalgirio      Oršos         "Salaspilio"
#         ------------  ------------  ------------  ------------  ------------ 
data <- c("1236-09-22", "1260-07-13", "1410-07-15", "1514-09-08", "1605-09-27")
t <- as.Date(data, format = "%Y-%m-%d")
t
#> [1] "1236-09-22" "1260-07-13" "1410-07-15" "1514-09-08" "1605-09-27"

diff(t)
#> Time differences in days
#> [1]  8695 54787 38040 33257

as.difftime()

Jei duotas laiko skirtumų vektorius, tada į difftime formatą jis paverčiamas naudojant funkciją as.difftime().

Argumentas Reikšmė
tim laiko skirtumų vektorius, character arba numeric
format formatas, kuriuo užrašytas laiko skirtumas
units laiko matavimo vienetai, standartiškai “auto”

Pavyzdžiui, žinomas tam tikrų įvykių laiko trukmės vektorius. Sudarysime laiko skirtumų vektorių.

Kodas
s <- c("01:54:02", "02:11:32", "02:26:45", "02:44:49", "02:57:09", "03:11:08")

d <- as.difftime(s, format = "%H:%M:%S", units = "hours")
d
#> Time differences in hours
#> [1] 1.900556 2.192222 2.445833 2.746944 2.952500 3.185556

difftime klasės laiko skirtumus galima apvalinti, sumuoti ir vidurkinti arba skaičiuoti įvairias kitas statistines charakteristikas.

Kodas
min(d)
#> Time difference of 1.900556 hours
max(d)
#> Time difference of 3.185556 hours
range(d)
#> Time differences in hours
#> [1] 1.900556 3.185556
quantile(d)
#> Time differences in hours
#>       0%      25%      50%      75%     100% 
#> 1.900556 2.255625 2.596389 2.901111 3.185556

mean(d)
#> Time difference of 2.570602 hours
sum(d)
#> Time difference of 15.42361 hours

Laiko skirtumai gali būti duoti kaip skaitinių reikšmių vektorius. Pavyzdžiui, tie patys laiko skirtumai galėjo būti išreikšti sekundėmis.

Kodas
s <- c(6842, 7892, 8805, 9889, 10629, 11468)

d <- as.difftime(s, units = "secs")
d
#> Time differences in secs
#> [1]  6842  7892  8805  9889 10629 11468

Kartais reikia žinoti, kiek laiko užtrunka tam tikri skaičiavimai. Pavyzdžiui, gali dominti, kiek laiko užtrunka viena ciklo iteracija arba reikia nustatyti, kuri iš dviejų alternatyvių komandų įvykdoma greičiau.

Norint sužinoti skaičiavimų trukmę, reikia užfiksuoti laiką, kada prasideda ir kada baigiasi skaičiavimai. Tam galima naudoti standartinę funkciją Sys.time(). Pavyzdžiui, apskaičiuosime, kiek laiko užtrunka 100 vektorių su normaliosiomis atsitiktinėmis reikšmėmis generavimas ir vidurkinimas.

Kodas
start <- Sys.time()

  for (i in 1:100) {
    x <- rnorm(1000)
    v <- mean(x)   
  }

stop <- Sys.time()

difftime(stop, start, units = "secs")
#> Time difference of 0.01989818 secs

Tam pačiam tikslui galima panaudoti ir funkciją proc.time(), kuri parodo, kiek laiko veikia R.

Kodas
start <- proc.time()
 
  for (i in 1:100) {
    x <- rnorm(1000)
    v <- mean(x)   
  }

stop <- proc.time()

stop - start
#> vartotojas    sistema    praėjęs 
#>       0.01       0.00       0.01

Jeigu išraiška užrašoma kompaktiškai, tada jos vykdymo trukmę galima nustatyti įdėjus ją į funkciją system.time(). Pvz., nustatysime, kuri iš dviejų funkcijų greičiau apskaičiuoja matricos stulpelių vidurkius.

Kodas
n <- 1000
m <- matrix(rnorm(n*n), ncol = n, nrow = n)

system.time(apply(m, 2, mean))
#> vartotojas    sistema    praėjęs 
#>       0.03       0.00       0.03
system.time(colMeans(m))
#> vartotojas    sistema    praėjęs 
#>       0.00       0.00       0.01
Užduotis
  1. Nustatykite laiko tarpus tarp gretimų pilnų Saulės užtemimų 2016–2021 metų laikotarpyje.
  2. Garsioji Halio kometa paskutinį kartą buvo matoma 1986 metais, o perihelyje buvo tų pačių metų vasario 9 d. Jos periodas kintantis, vidutiniškai sudaro 75,3 metus. Nustatykite, sekančio perihelio datą. Kokia gauta paklaida, jei tiksliai žinoma, kad sekantis perihelis bus 2061 liepos 28 dieną?