Rozdział 7 Czas i napisy
W meteorologii i klimatologii niezmiernie ważne jest analizowanie zbiorów danych w aspekcie czasowym. Przed rozpoczęciem analizy szeregów czasowych niezbędne jest zrozumienie sposobu przechowywania tego typu danych przez komputer.
W R powszechnie stosowane są 2-3 formaty przechowywania czasu:
Klasa
Date
- wystarczająca jeśli nie mamy danych o rozdzielczości mniejszej niż dobowa (sub-daily) oraz nasze dane nie wymagają różnic w zmianach czasu urzędowegoKlasy POSIX-owe:
POSIXct
orazPOSIXlt
(odpowiednio: calendar i local time). Zdecydowanie częściej stosowana jest klasaPOSIXct
, która pozwala na przechowywanie czasu z dokładnością do sekundy (lub jej części ułamkowych). Poza tym obsługuje kwestie problematyczne związane z różnymi strefami czasowymi oraz zmianą czasu.
7.1 Date
Konstruktorem klasy Date jest funkcja as.Date()
.
Jako pierwszy argument przyjmuje wektor napisów opisujących daty. Drugi opcjonalny argument określa formatowanie daty. Domyślne formatowanie to rok-miesiąc-dzień.
as.Date("2015-02-22")
## [1] "2015-02-22"
Jeśli chcemy zmienić sposób deklarowania daty możemy użyc argumentu format
as.Date("02/22/2015", format = "%m/%d/%Y")
## [1] "2015-02-22"
Aby uzyskać dokładną pomoc dotyczącą oznaczeń w formatowaniu daty należy otworzyć plik pomocy instrukcją ?strptime
.
Obiekty klasy Date można tworzyć także na podstawie liczb całkowitych lub obiektów klasy POSIXct, w obu przypadkach przy pomocy funkcji as.Date()
.
Zadanie sprawdzające
- Utwórz dowolnie nazwany obiekt przechowujący dzisiejszą datę
- Dodaj lub odejmij od niego dowolną liczbę całkowitą oraz wektor w postaci sekwencji liczb wygenerowanych za pomocą operatora
:
- W R daty przechowywane są również jako liczby. Sprawdź działanie funkcji
as.numeric()
na dowolnym obiekcie klasy Date. Jaki dzień to dla komputera 0?
7.1.1 W jaki sposób najszybciej utworzyć ciąg dat?
Bardzo często zdarza się, że konieczne jest wygenerowanie ciągu dat, które będziemy umieszczać w jednej z kolumn ramki danych. Podobnie jak w przypadku “normalnych” wektorów również do tego celu możemy zastosować funkcję seq
, która w przypadku operacji na datach ma także postać rozszerzoną jako seq.Date()
. Sprawdź pomoc dla tej funkcji. Następnie:
- Utwórz datę początkową i końcową dla generowanego ciągu dat:
poczatek <- as.Date("2016-01-01")
koniec <- as.Date("2016-12-31")
- Podłącz wygenerowane obiekty jako argumenty
from
orazto
dla funkcjiseq.Date()
oraz opcjęby
jako dzień (ang. day):
naszedaty <- seq.Date(from=poczatek, to=koniec, by="day")
head(naszedaty)
## [1] "2016-01-01" "2016-01-02" "2016-01-03" "2016-01-04" "2016-01-05"
## [6] "2016-01-06"
- Czasem jednak niezbędne jest wygenerowanie dat w pewnych interwałach czasu, np. co tydzień, albo co kilka- kilkanaście dni. Do tego celu można użyć opcji
by
. Przykładowo, daty z interwałem co tydzień, można wygenerować wg jednej z poniższych opcji:
cotydzien1 <- seq.Date(from=poczatek, to=koniec, by="week")
cotydzien2 <- seq.Date(from=poczatek, to=koniec, by="7 days")
head(cotydzien1)
## [1] "2016-01-01" "2016-01-08" "2016-01-15" "2016-01-22" "2016-01-29"
## [6] "2016-02-05"
head(cotydzien2)
## [1] "2016-01-01" "2016-01-08" "2016-01-15" "2016-01-22" "2016-01-29"
## [6] "2016-02-05"
7.1.2 Operowanie datami
Wiele operacji na datach nie należy do trywialnych lub intuicyjnych. Przykładowo, jeśli chcemy wyciągnać z obiektu klasy Date jaki to jest dzień tygodnia możemy posłużyć się opcją formatowania opisaną w systemie pomocy pod hasłem ?strptime
. Sprawdźmy na przykładzie dla obiektu naszedaty
:
dnitygodnia <- format(naszedaty,"%A")
head(dnitygodnia)
## [1] "Friday" "Saturday" "Sunday" "Monday" "Tuesday" "Wednesday"
7.1.3 Biblioteka lubridate
Znaczna część operacji na datach jest usprawniona dzięki pakietom R, dedykowanym do pracy na obiektach zawierających czas. Jednym z nich jest biblioteka lubridate
. Aby z niej korzystać należy ją zainstalować i aktywować.
#install.packages("lubridate") # jesli nie byl wczesniej zainstalowany
library(lubridate)
Przyjrzyjmy się działaniu przykładowych funkcji z tego pakietu:
now()
## [1] "2018-06-21 21:43:38 CEST"
today()
## [1] "2018-06-21"
dzis <- today()
week(dzis)
## [1] 25
day(dzis)
## [1] 21
month(dzis)
## [1] 6
months(dzis)
## [1] "June"
year(dzis)
## [1] 2018
Zadanie
- Oblicz ile dni trwała druga wojna światowa w Europie (1. września 1945 - 8 maja 1945).
- Sprawdź jaki dzień tygodnia będzie za 100 dni od dziś
7.2 POSIXct
Konstruktorem klasy POSIXct jest funkcja as.POSIXct()
. Jako pierwszy argument przyjmuje wektor napisów opisujących chwile czasu. Drugi opcjonalny argument określa formatowanie daty. Domyślne formatowanie to rok-miesiąc-dzień godzina:minuta:sekunda.
Aby uzyskać dokładną pomoc dotyczącą oznaczeń w formatowaniu daty należy otworzyć plik pomocy instrukcją ?strptime.
czas1 <- as.POSIXct("2015-02-13 12:56:26")
czas1
## [1] "2015-02-13 12:56:26 CET"
czas2 <- as.POSIXct("14022015 12:56:26", format = "%d%m%Y %H:%M:%S")
czas2
## [1] "2015-02-14 12:56:26 CET"
Na czasach można wykonywać takie operacje jak odejmowanie czy dodawane do określonego przedziału czasu (dodanie liczby całkowitej, domyślnie dodaje określoną liczbę sekund).
czas2 - czas1
## Time difference of 1 days
Możemy także sprawdzić lub nadać właściwości związane ze strefą czasową:
tz(czas2)
## [1] ""
… choć niektóre rzeczy łatwiej zrobić za pomocą klasycznych instrukcji POSIXowych. Sprawdźmy różnicę czasu pomiędzy Jerozolimą i Warszawą w dn. 21 czerwca:
warszawa <- as.POSIXct("2017-06-21 16:00:00", tz = "Europe/Warsaw")
jerozolima <- as.POSIXct("2017-06-21 16:00:00", tz = "Asia/Jerusalem")
jerozolima-warszawa
## Time difference of -1 hours
Zadanie domowe
- Wczytaj plik z danymi dostępnymi na stronie http://enwo.pl/przetwarzanie/dane/poz.txt .
- Następnie przekonwertuj kolumnę/kolumny reprezentujące czas na nową kolumnę zawierającą czas jako obiekt klasy
Date
. Możesz także utworzyć więcej nowych kolumn w zależności od własnych potrzeb. - Oblicz średnią wartość temperatury dla wybranego (jednego miesiąca).
Zadanie podsumowujące
TBA