Praca z datami w języku R (podstawowe możliwości oraz pakiety lubridate i timeperiodsR)

Uzyskaj bieżącą datę w każdym języku programowania, operacja porównywalna z "Hello world!". Język R nie jest wyjątkiem.

W tym artykule omówimy, jak działa zarządzanie datami w podstawowej składni języka R oraz zaprezentujemy kilka przydatnych pakietów, które rozszerzają jego możliwości w pracy z datami:

  • lubridate — pakiet umożliwiający wykonywanie obliczeń arytmetycznych między datami;
  • timeperiodsR — pakiet do pracy z przedziałami czasowymi i ich komponentami.

Praca z datami w języku R (podstawowe możliwości oraz pakiety lubridate i timeperiodsR)

Spis treści

Jeśli interesujesz się analizą danych, a szczególnie językiem R, mogą cię zainteresować moje telegram i youtube kanały. Większość ich treści poświęcona jest językowi R.

  1. Zarządzanie datami w podstawowej składni R
    1.1. Konwersja tekstu na datę
    1.2. Wyodrębnianie komponentów daty w podstawowym R
  2. Zarządzanie datami za pomocą pakietu lubridate
    2.1. Konwersja tekstu na datę z użyciem lubridate
    2.2. Wyodrębnianie komponentów dat za pomocą pakietu lubridate
    2.3. Operacje arytmetyczne na datach
  3. Uproszczona praca z okresami, pakiet timeperiodsR
    3.1. Przedziały czasowe w timeperiodsR
    3.2. Filtracja wektora dat za pomocą timeperiodsR
  4. Podsumowanie

Zarządzanie datami w podstawowej składni R

Konwersja tekstu na datę

W podstawowym R istnieje zestaw funkcji do zarządzania datami. Minusem podstawowej składni jest to, że nazwy i argumenty funkcji są bardzo rozproszone i nie mają praktycznie żadnego logicznego powiązania. Niemniej jednak, podstawowe funkcje języka są istotne, dlatego rozpoczniemy od nich.

Najczęściej, podczas ładowania danych w R z plików csv lub innych źródeł, otrzymujesz datę w postaci tekstu. Aby przekonwertować ten tekst na właściwy typ danych, użyj funkcji as.Date().

# создаём текстовый вектор с датами
my_dates <- c("2019-09-01", "2019-09-10", "2019-09-23")

# проверяем тип данных
class(my_dates)

#> [1] "character"

# преобразуем текст в дату
my_dates <- as.Date(my_dates)

# проверяем тип данных
class(my_dates)

#> [1] "Date"

Domyślnie as.Date() która przyjmuje datę w dwóch formatach: RRRR-MM-DD lub RRRR/MM/DD.
Jeśli w twoim zbiorze danych daty są przedstawione w innym formacie, możesz użyć argumentu format.

as.Date("September 26, 2019", format = "%B %d, %Y")

format przyjmuje w postaci tekstowej operatory oznaczające jakiś przedział czasowy i jego format, najczęściej używane wartości przedstawione są w tabeli poniżej:

Format
Opis

%d
Numer dnia w miesiącu

%a
Skrót nazwy dnia tygodnia

%A
Pełna nazwa dnia tygodnia

%w
Numer dnia tygodnia (0-6, gdzie 0 to niedziela)

%m
Dwucyfrowe oznaczenie miesiąca (01-12)

%b
Skrót nazwy miesiąca (apr, mar, …)

%B
Pełna nazwa miesiąca

%y
Dwucyfrowe oznaczenie roku

%Y
Czterocyfrowe oznaczenie roku

%j
Numer dnia w roku (001 — 366)

%U
Numer tygodnia w roku (00 — 53), początek tygodnia Niedziela

%W
Numer tygodnia w roku (00 — 53), początek tygodnia Poniedziałek

Odpowiednio, "26 września 2019" to pełna nazwa miesiąca, dzień i rok. Opisać ten format daty operatorami można tak:"%B %d, %Y".

Gdzie:

  • %B — Pełna nazwa miesiąca
  • %d — Numer dnia w miesiącu
  • %Y — Czterocyfrowe oznaczenie roku

Przy opisywaniu formatu daty ważne jest, aby uwzględnić wszystkie dodatkowe znaki z twojego ciągu, na przykład myślniki, przecinki, kropki, spacje itd. W moim przykładzie, "26 września 2019", po dacie stoi przecinek, i w opisie formatu również trzeba postawić przecinek:"%B %d, %Y".

Są sytuacje, kiedy otrzymujesz datę, która nie tylko nie odpowiada standardowym formatom (RRRR-MM-DD lub RRRR/MM/DD), ale też jest w języku, który różni się od ustawionego jako domyślny w twoim systemie operacyjnym. Na przykład, załadowałeś dane, gdzie data została podana w następujący sposób: "15 grudnia 2019 r.". Przed konwersją tego ciągu na datę, należy zmienić lokalizację.

# Меняем локаль
Sys.setlocale("LC_TIME", "Russian")
# Конвертируем строку в дату
as.Date("Декабрь 15, 2019 г.", format = "%B %d, %Y")

Wyodrębnianie komponentów daty w podstawowym R

W podstawowym R nie ma zbyt wielu funkcji, które pozwalają wyodrębnić jakąkolwiek część daty z obiektu klasy Date.

current_date <- Sys.Date() # bieżąca data
weekdays(current_date)     # uzyskać numer dnia tygodnia
months(current_date)       # uzyskać numer miesiąca w roku
quarters(current_date)     # uzyskać numer kwartału w roku

Oprócz podstawowej klasy obiektów Date w podstawowym R są jeszcze 2 typy danych, które przechowują znacznik czasu: POSIXlt, POSIXct. Główna różnica między tymi klasami a Date polega na tym, że oprócz daty przechowują również czas.

# получить текущую дату и время
current_time <- Sys.time()

# узнать класс объекта current_time 
class(current_time)

# "POSIXct" "POSIXt"

veth_xdp_flush_bq() Sys.time() zwraca bieżącą datę i czas w formacie POSIXct. Ten format pod względem znaczenia jest podobny do UNIXTIME, i przechowuje ilość sekund od początku ery UNIX (północ (UTC) z 31 grudnia 1969 roku na 1 stycznia 1970).

Klasa POSIXlt przechowuje również czas i datę oraz wszystkie ich komponenty. Dlatego jest obiektem o bardziej skomplikowanej strukturze, z której łatwo można uzyskać każdy komponent daty i czasu, ponieważ w zasadzie POSIXlt to list.

# Получаем текущую дату и время
current_time_ct <- Sys.time()

# Преобразуем в формат POSIXlt
current_time_lt <- as.POSIXlt(current_time_ct)

# извлекаем компоненты даты и времени
current_time_lt$sec   # секунды
current_time_lt$min   # минуты
current_time_lt$hour  # часы
current_time_lt$mday  # день месяца
current_time_lt$mon   # месяц
current_time_lt$year  # год
current_time_lt$wday  # день недели
current_time_lt$yday  # день года
current_time_lt$zone  # часовой пояс

Konwersja danych numerycznych i tekstowych na formaty POSIX* jest realizowana za pomocą funkcji as.POSIXct() i as.POSIXlt(). Te funkcje mają niewielki zestaw argumentów.

  • x — Liczba, ciąg lub obiekt klasy Date, który należy przekształcić;
  • tz — Strefa czasowa, domyślnie "GMT";
  • format — Opis formatu daty, w którym przedstawione są dane przekazywane w argumencie x;
  • origin — Używane tylko podczas konwersji liczby na POSIX, do tego argumentu należy przekazać obiekt daty i czasu, od którego zaczyna się odliczanie sekund. Zwykle jest używane do konwersji z UNIXTIME.

Jeśli Twoje dane dotyczące daty i czasu są przedstawione w UNIXTIME, to aby je skonwertować na zrozumiałą, czytelną datę, użyj następującego przykładu:

# Конвертируем UNIXTIME в читаемую дату 
as.POSIXlt(1570084639,  origin = "1970-01-01")

W origin możesz określić dowolny znacznik czasu. Na przykład, jeśli w Twoich danych data i czas są podane jako liczba sekund od 15 września 2019 roku, godzina 12:15, to aby przekształcić je w datę użyj:

# Конвертируем UNIXTIME в дату учитывая что начало отсчёта 15 сентября 2019 12:15
as.POSIXlt(1546123,  origin = "2019-09-15 12:15:00")

Zarządzanie datami za pomocą pakietu lubridate

lubridate to prawdopodobnie najpopularniejszy pakiet do pracy z datami w języku R. Dodatkowo oferuje Ci jeszcze trzy klasy.

  • durations — długości, czyli liczba sekund między dwoma znacznikami czasu;
  • periods — okresy pozwalają na wykonywanie obliczeń między datami w ludzkich jednostkach: dniami, miesiącami, tygodniami i tak dalej;
  • intervals — obiekty zapewniające początkowy i końcowy moment czasu.

Instalacja dodatkowych pakietów w języku R odbywa się standardową funkcją install.packages().

Instalacja pakietu lubridate:

install.packages("lubridate")

Konwersja tekstu na datę z użyciem lubridate

Funkcje pakietu lubridate znacznie upraszczają proces konwersji tekstu na datę, a także pozwalają na przeprowadzanie wszelkich operacji arytmetycznych na datach i czasach.

Aby uzyskać bieżącą datę lub datę i czas, pomogą Ci funkcje today() i now().

today() # bieżąca data
now()   # bieżąca data i czas

Aby przekształcić ciąg tekstowy na datę w lubridate istnieje całe mnóstwo funkcji, których nazwy zawsze składają się z trzech liter i oznaczają kolejność komponentów daty:

  • y — rok
  • m — miesiąc
  • d — dzień

Lista funkcji do konwersji tekstu na datę za pomocą lubridate

  • ymd()
  • ydm()
  • mdy()
  • myd()
  • dmy()
  • dym()
  • yq()

Kilka przykładów konwersji ciągów na daty:

ymd("2017 jan 21")
mdy("March 20th, 2019")
dmy("1st april of 2018")

Jak widzisz, lubridate znacznie bardziej efektywnie potrafi rozpoznać opisy dat w formie tekstu i pozwala Ci przekształcać tekst w daty bez użycia dodatkowych operatorów do opisu formatu.

Wyodrębnianie komponentów dat za pomocą pakietu lubridate

Można również za pomocą lubridate uzyskać dowolny komponent z daty:

dt <- ymd("2017 jan 21")

year(dt)  # rok
month(dt) # miesiąc
mday(dt)  # dzień w miesiącu
yday(dt)  # dzień w roku
wday(dt)  # dzień tygodnia

Operacje arytmetyczne na datach

Jednak najważniejsza i podstawowa funkcjonalność lubridate polega na możliwości przeprowadzania różnych operacji arytmetycznych na datach.

Zaokrąglanie daty odbywa się za pomocą trzech funkcji:

  • floor_date — zaokrąglanie do najbliższego przeszłego czasu
  • ceiling_date — zaokrąglanie do najbliższego przyszłego czasu
  • round_date — zaokrąglanie do najbliższego czasu

Każda z tych funkcji ma argument unit, który pozwala wskazać jednostkę zaokrąglania: sekunda, minuta, godzina, dzień, tydzień, miesiąc, dwa miesiące, kwartał, sezon, pół roku, rok

dt <- ymd("2017 jan 21")

round_date(dt, unit = "month")    # zaokrąglić do miesiąca
round_date(dt, unit = "3 month")  # zaokrąglić do 3 miesięcy
round_date(dt, unit = "quarter")  # zaokrąglić do kwartału
round_date(dt, unit = "season")   # zaokrąglić do sezonu
round_date(dt, unit = "halfyear") # zaokrąglić do półrocza

Zatem przyjrzyjmy się, jak uzyskać datę, która będzie za 8 dni po aktualnej dacie i przeprowadzić różne inne obliczenia arytmetyczne między dwiema datami.

today() + days(8)   # jaka będzie data za 8 dni
today() - months(2) # jaka była data 2 miesiące temu
today() + weeks(12) # jaka będzie data za 12 tygodni
today() - years(2)  # jaka była data 2 lata temu

Ułatwiona praca z okresami, pakiet timeperiodsR.

timeperiodsR — nowy pakiet do pracy z datami, który został opublikowany na CRAN we wrześniu 2019 roku.

Instalacja pakietu timeperiodsR:

install.packages("timeperiodsR")

Główne przeznaczenie — szybkie określenie pewnego przedziału czasowego względem podanej daty. Na przykład za pomocą jego funkcji łatwo możesz:

  • Uzyskać poprzedni tydzień, miesiąc, kwartał lub rok w R.
  • Uzyskać zadaną liczbę przedziałów czasowych względem daty, na przykład poprzednie 4 tygodnie.
  • Łatwo wydobywać z uzyskanego przedziału jego składniki: datę początkową i końcową, liczbę dni w przedziale, całą sekwencję dat, które się do niego wchodzą.

Nazwy wszystkich funkcji pakietu timeperiodsR są intuicyjnie zrozumiałe i składają się z dwóch części: kierunek_przedział, gdzie:

  • kierunek w którym należy się poruszać względem podanej daty: last_n, previous, this, next, next_n.
  • czasowy przedział do obliczania okresu: dzień, tydzień, miesiąc, kwartał, rok.

Pełny zestaw funkcji:

  • last_n_days()
  • last_n_weeks()
  • last_n_months()
  • last_n_quarters()
  • last_n_years()
  • previous_week()
  • previous_month()
  • previous_quarter()
  • previous_year()
  • this_week()
  • this_month()
  • this_quarter()
  • this_year()
  • next_week()
  • next_month()
  • next_quarter()
  • next_year()
  • next_n_days()
  • next_n_weeks()
  • next_n_months()
  • next_n_quarters()
  • next_n_years()
  • custom_period()

Przedziały czasowe w timeperiodsR

Te funkcje są przydatne, gdy konieczne jest sporządzanie raportów na podstawie danych za ubiegły tydzień lub miesiąc. Aby uzyskać poprzedni miesiąc, skorzystaj z funkcji o tej samej nazwie previous_month():

prmonth <- previous_month()

Po czym otrzymasz obiekt prmonth klasy tpr, z którego łatwo można uzyskać następujące komponenty:

  • datę rozpoczęcia okresu, w naszym przykładzie to zeszły miesiąc
  • datę zakończenia okresu
  • liczbę dni wchodzących w okres
  • sekwencję dat wchodzących w okres

Możliwe jest uzyskanie każdego z komponentów na różne sposoby:

# первый день периода
prmonth$start
start(prmonth)

# последний день периода
prmonth$end
end(prmonth)

# последовательность дат
prmonth$sequence
seq(prmonth)

# количество дней входящих в период
prmonth$length
length(prmonth)

Możesz również uzyskać dowolny z komponentów, korzystając z argumentu part, który jest obecny w każdej z funkcji pakietu. Możliwe wartości: start, end, sequence, length.

previous_month(part = "start")    # początek okresu
previous_month(part = "end")      # koniec okresu
previous_month(part = "sequence") # sekwencja dat
previous_month(part = "length")   # liczba dni w okresie

Zatem rozważmy wszystkie argumenty dostępne w funkcjach pakietu timeperiodsR:

  • x — Data odniesienia, od której będzie obliczany okres czasu, domyślnie bieżąca data;
  • n — Liczba interwałów, które wejdą w okres, na przykład 3 poprzednie tygodnie;
  • part — Jaki komponent obiektu tpr należy uzyskać, domyślnie wszystko;
  • week_start — Argument występuje tylko w funkcjach do pracy z tygodniami i pozwala określić numer dnia tygodnia, który będzie uważany za jego początek, domyślnie początkiem tygodnia jest poniedziałek, ale można określić dowolny dzień od 1 — poniedziałek do 7 — niedziela.

W ten sposób można obliczać dowolny okres czasu względem bieżącej lub dowolnej innej daty, podam jeszcze kilka przykładów:

# получить 3 прошлые недели
# от 6 октября 2019 года
# начало недели - понедельник
last_n_weeks(x = "2019-10-06", 
             n = 3, 
             week_start = 1)

 Okres czasu: od 9 września 2019 roku, poniedziałek do 29 września 2019 roku, niedziela

6 października to niedziela:
Praca z datami w języku R (podstawowe możliwości oraz pakiety lubridate i timeperiodsR)

Potrzebujemy okresu, który względem 6 października weźmie 3 poprzednie tygodnie. Nie wliczając tygodnia, w który wchodzi sam 6 października. Zgodnie z tym jest to okres od 9 do 29 września.

Praca z datami w języku R (podstawowe możliwości oraz pakiety lubridate i timeperiodsR)

# получить месяц отстающий на 4 месяца
# от 16 сентября 2019 года
previous_month(x = "2019-09-16", n = 4)

 Okres czasu: od 1 maja 2019 roku, środa do 31 maja 2019 roku, piątek

W tym przykładzie interesuje nas miesiąc, który był 4 miesiące temu, jeśli odrzucimy od 16 września 2019 roku, więc był to maj 2019 roku.

Filtracja wektora dat za pomocą timeperiodsR

Dla filtrowania dat w timeperiodsR jest kilka operatorów:

  • %left_out% — porównuje dwa obiekty klasy tpr i zwraca wartość z lewego, która nie jest obecna w prawym.
  • %left_in% — porównuje dwa obiekty klasy tpr i zwraca daty z lewego obiektu, które wchodzą w prawy.
  • %right_out% — porównuje dwa obiekty klasy tpr i zwraca wartość z prawego, która nie jest obecna w lewym.
  • %right_in% — porównuje dwa obiekty klasy tpr i zwraca daty z prawego obiektu, które znajdują się w lewym.

period1 <- this_month("2019-11-07")
period2 <- previous_week("2019-11-07")

period1 %left_in% period2   # uzyskaj daty z period1, które są w period2
period1 %left_out% period2  # uzyskaj daty z period1, które nie są w period2
period1 %right_in% period2  # uzyskaj daty z period2, które są w period1
period1 %right_out% period2 # uzyskaj daty z period2, które nie są w period1

Pakiet timeperiodsR ma oficjalny, polskojęzyczny playlist na YouTube.

Podsumowanie

Szczegółowo omówiliśmy klasy obiektów przeznaczone w języku R do pracy z datami. Teraz potrafisz także przeprowadzać operacje arytmetyczne na datach i szybko uzyskiwać dowolne okresy czasu za pomocą pakietu timeperiodsR.

Jeśli interesuje Cię język R, zapraszam do subskrypcji mojego kanału na Telegramie R4marketing, w którym codziennie dzielę się przydatnymi materiałami na temat zastosowania języka R w rozwiązywaniu codziennych zadań.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster