19  Práce s časovými daty

V této kapitole nás čeká práce s časovými daty, jednou z nejzákeřnějších věcí, se kterou se při analýze dat můžeme setkat. Naštěstí pro nás ale Tidyverse obsauje balíček lubridate, který nám naše snažení usnadní.

19.1 Epochy aneb jak počítače měří čas

Než se podíváme na funkce, které Rko pro práci s časovými daty poskytuje, vyplatí se zamyslet nad tím, jak se vlastně čas měří. Primární zákeřností času je, že je relativní - je vždy měřen relativně vůči určitému bodu. Například, v okamžiku psaní tohoto textu je 21. 7. 2025 16:46. Co to znamená? Že v tomto okamžiku uběhlo 2025 let, 7 měsíců, 21 dní, 16 hodin a 46 minut od začátku Gregoriánského kalendáře, tedy od 1. ledna roku 0. Tomuto bodu se v technické terminologii říká počátek epochy. Ne všechny kultury ovšem odvozují své chápání času od křesťanského (Gregoriánského) kalendáře - podle Islámského kalendáře se v době vzniku tohoto textu píše rok 1447, podle Hebrejského potom 5785.

Počítače měří čas obdobně jako lidé, tedy od začátku epochy. Odlišují se ovšem dvěma věcmi:

  1. Počítače měří čas mnohem precizněji. Základní jednotkou měření času nejsou roky, dny ani minuty, ale vteřiny.

  2. Počítače mají své vlastní epochy. Podobně jako lidé, ani stroje se jednomyslně neshodnou na tom, od kdy jakého okamžiku by se měl čas měřit, zdaleka nejpoužívanější je ale takzvaná Unix epocha, která začíná o půlnoci 1. ledna 1970.

Zatímco mi bychom tedy řekli, že dnes je 21.7. 2025, pro Rko je 1 753 107 850 vteřin od 1. 1. 1970. V tuto chvíli možná některé z nás napadne otázka, proč je důležité o epochách vědět. Důvody jsou dva. Tím prvním je, že jakmile si uvědomíme, že čas je jen počet vteřin od od určitého okamžiku, můžeme s časovými daty pracovat jako s jakkýmikoliv numerickými proměnnými. Časové okamžiky je od sebe možné odčítat, přičítat, dělit a podobně. Druhým z důvodů je, abychom dokázali čelit problémům, které při převodu mezi epochami mohou nastat. Již jsme zmínili, že Rko (a většina počítačových programů) počítá čas od 1. ledna 1970. Ne všechny populární programy ale dodržují tuto konvenci. Nejvíce rozšířenou vyjímkou je Microsoft Excel, který za počátek epochy považuje 1. leden 1900. Ve většině případů se modernímu softwaru daří převádět mezi epochami automaticky. Pokud byste ovšem v budoucnu naimportovali data z Excelu do Rka a zjistili, že všechna časová data jsou o circa 70 posunutá, tak už budete vědět, v čem je podstata problému.

19.2 Vytváření časových proměnných

Rko a balíček lubridate poskytují několik funkcí pro vytváření časových proměnných. Situaci komplikuje fakt, že lidé z různých částí světa mají tendenci zapisovat čas různými způsoby. Standardní, mezinárodní formát je takzvaný ISO8601. V Rámci tohoto formátu se čas zapisuje od nějvětší jednotky (roku) po nejmenší (den), přičemž jednotky jsou odděleny pomlčkou. Například 2025-07-21. Pokud proměnná zaznamená i menší jednotky (hodiny, minuty, vteřiny, …), jsou od data odděleny mezerou od sebe dvojtečkou, např. 2025-07-21 16:46. Pokud jsou vaše data formátovány takto, Rko nebude mít problém je zpracovat. Ne vždy ale budeme mít takové štěstí. V severní Americe je například zvykem zapisovat časová data ve formátu měsíc-den-rok. Občas také místo čísel používají názvy měsíců nebo jejich zkratky (“January” nebo “Jan”).

lubridate naštěstí obsahuje hned několik funkcí, které nám import atypických formátů usnaďnují. Pro jejich aplikaci stačí specifikovat pořadí roku (y), měsíce (m) a dne (d), případě hodiny (h), minuty (m) a vteřiny (s). Například:

ymd("2025-07-21")
[1] "2025-07-21"
mdy("July 21st, 2025")
[1] "2025-07-21"
dmy("21-Jul-2025")
[1] "2025-07-21"
ymd_hms("2025-07-21 16:46:59")
[1] "2025-07-21 16:46:59 UTC"
mdy_hm("07/21/2025 16:46")
[1] "2025-07-21 16:46:00 UTC"

Kromě vytváření časových dat z textových řetězců můžeme také jednoduše zjistit současný čas pomocí funkcí today() a now():

today() #současné datum
[1] "2025-10-03"
now() #současné datum včetně hodiny, minuty a vteřiny
[1] "2025-10-03 11:41:29 CEST"

19.3 Formátování časových proměnných

V závislosti na situaci budeme potřebovat zobrazovat časová data různými způsoby. K tomu nám poslouží obecná funkce format(). Například klasické české formátování získáme pomocí:

current_date <- as_date("2025-07-21")
format(current_date, "%d. %m. %Y")
[1] "21. 07. 2025"

Funkce format() využívá speciálních znaků, začínajících %. Například čtyřmístné označení roku je %Y, zatímco dvoumístné označení pomocí %y. Ostatní znaky (například tečky a čářky) jsou zobrazovány klasickým způsobem. Přehled nejpoužívanějších speciálních znaků uvádíme v následující tabulce.

Typ Znak Význam Příklad
Rok %Y 4-místný rok 2021
Rok %y 2-místný rok 21
Měsíc %m měsíc jako čislice 2
Měsíc %b Zkrácený měsíc (v jazyce R) Feb
Měsíc %B Plný název měsíce February
Den %d Den jako číslice (bez nul) 2
Den %e Den jako číslice (s nulami) 02
Čas %H Hodina (24 hodin) 13
Čas %I Hodina (12 hodin) 1
Čas %p AM/PM pm
Čas %M Minuty 35
Čas %S Vteřiny 45

Pro představu si můžeme si můžeme ukázat pár příkladů:

format(current_date, "%d. %B %Y")
[1] "21. July 2025"
format(current_date, "Year %Y (%B)")
[1] "Year 2025 (July)"
format(current_date, "%e. %m. %y")
[1] "21. 07. 25"

19.4 Transformace časových dat

Z existujících časových dat můžeme vyextrahovat jednotlivé komponenty pomocí funkcí year(), month(), day(), hour(), minute() a second() z balíčku lubridate. To se hodí zejména v situacích, kdy máme velmi podrobná časová data, z nichž pro nás je ale relevatní například jen rok.

current_date <- as_date("2025-07-21")
year(current_date)
[1] 2025
day(current_date)
[1] 21

Alternativně můžeme datum zaokrouhlit na nejbližší jednotky, například na nejbližší rok:

round_date(current_date, "year")
[1] "2026-01-01"

Častou aktivitou při práci s časovými daty je výpočet časových intervalů. Vraťme se k našemu datasetu countries, který obsahuje informace a roku založení každého státu. Nás by ale spíše zajímalo, kolik času již od založení uběhlo, tedy jak starý každý stát je. Naštěstí pro nás, s časovými daty se dá pracovat stejně, jako s numerickými a stačí nám tedy odečíst současné datum (funkce today()) od proměnné foundation_date. Výsledkem je počet dní od založení. Protože ale počítat stáří národních států na dny není moc praktické, převedeme výsledek na roky pomocí funkce time_length():

countries %>%
    select(foundation_date) %>%
    mutate(country_age = today() - foundation_date,
           country_age_years = time_length(country_age, "years"))
# A tibble: 38 × 3
   foundation_date country_age country_age_years
   <date>          <drtn>                  <dbl>
 1 1831-07-21       70932 days             194. 
 2 1989-11-10       13111 days              35.9
 3 1993-01-01       11963 days              32.8
 4 2053-05-19      -10090 days             -27.6
 5 1949-05-23       27892 days              76.4
 6 1918-02-24       39303 days             108. 
 7 1937-12-29       32055 days              87.8
 8 1975-11-19       18216 days              49.9
 9 1978-12-06       17103 days              46.8
10 1958-10-05       24470 days              67.0
# ℹ 28 more rows