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ędowego

  • Klasy POSIX-owe: POSIXct oraz POSIXlt (odpowiednio: calendar i local time). Zdecydowanie częściej stosowana jest klasa POSIXct, 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

  1. Utwórz dowolnie nazwany obiekt przechowujący dzisiejszą datę
  2. Dodaj lub odejmij od niego dowolną liczbę całkowitą oraz wektor w postaci sekwencji liczb wygenerowanych za pomocą operatora :
  3. 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:

  1. 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")
  1. Podłącz wygenerowane obiekty jako argumenty from oraz to dla funkcji seq.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"
  1. 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

  1. Oblicz ile dni trwała druga wojna światowa w Europie (1. września 1945 - 8 maja 1945).
  2. 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

  1. Wczytaj plik z danymi dostępnymi na stronie http://enwo.pl/przetwarzanie/dane/poz.txt .
  2. 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.
  3. Oblicz średnią wartość temperatury dla wybranego (jednego miesiąca).

Zadanie podsumowujące

TBA