Menu

Daty w R: as.Date, format() i arytmetyka dat

Klasa Date w R to liczba dni w przebraniu. Jak parsować napisy przez as.Date, formatować daty do wyświetlenia, odejmować je, tworzyć sekwencje i kiedy potrzebujesz POSIXct.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Data w R to liczba dni w przebraniu

Żeby zamienić napis w prawdziwą datę, użyj as.Date(); żeby pobrać dzisiejszą datę, użyj Sys.Date(). Za obiema stoi prosty trik: klasa Date w R to po prostu liczba, czyli liczba dni od 1 stycznia 1970, w przebraniu, dzięki któremu wypisuje się jak data z kalendarza. Przebranie zdejmiesz przez unclass():

To 20672 to surowa liczba dni i właśnie dzięki niej działa wszystko inne na tej stronie: porównania, odejmowanie i sekwencje to pod spodem zwykła arytmetyka liczb całkowitych. Przebranie sprawia, że da się tego używać: ta sama liczba wypisuje się jako data, formatuje jako data i ląduje na osi dat na wykresie.

as.Date() bez żadnej pomocy parsuje układ ISO "YYYY-MM-DD", co jest jednym z kilku dobrych powodów, by tak zapisywać daty w plikach. Jeden nawyk warto wyrobić wcześnie: nieudane parsowanie po cichu zwraca NA, a nie błąd, więc zawsze zerknij na wynik po sparsowaniu czegoś nowego.

Napisy, które tylko wyglądają jak daty, to wciąż zwykłe napisy: "2026-08-07" < "2026-11-01" przypadkiem porównuje się poprawnie, bo porządek ISO pokrywa się z alfabetycznym, ale "07/08/2026" sortuje się bez sensu. Najpierw konwertuj, potem porównuj.

Parsowanie innych układów przez format =

Świat nie zapisuje dat w ISO. Dla wszystkiego innego as.Date() przyjmuje argument format =: przepis opisujący przychodzący napis, zbudowany z kodów %.

Wszystkie trzy dają ten sam dzień. Przepis musi pasować do napisu dokładnie, łącznie z separatorami: "%d/%m/%Y" nie sparsuje "07-08-2026". Kody, których naprawdę będziesz używać:

KodZnaczeniePrzykład
%YRok, 4 cyfry2026
%yRok, 2 cyfry26
%mNumer miesiąca08
%dDzień miesiąca07
%bSkrócona nazwa miesiącaAug
%BPełna nazwa miesiącaAugust
%aSkrócony dzień tygodniaFri
%APełny dzień tygodniaFriday
%HGodzina (00-23)14
%MMinuta30
%SSekunda05

Klasyczna zasadzka to samo "07/08/2026": dzień/miesiąc/rok w większości świata, miesiąc/dzień/rok w USA, a R nie zgadnie, o co chodzi w twoim pliku. Co gorsza, złe założenie często "działa", bo oba odczyty to poprawne daty, aż do 13. dnia jakiegoś miesiąca, który parsuje się do NA (nie ma 13. miesiąca). Poznaj konwencję swoich danych, zanim napiszesz przepis.

Formatowanie dat do wyświetlenia

format() to lustrzane odbicie as.Date(): te same kody %, działające w przeciwną stronę. Na wejściu Date, na wyjściu napis.

Używaj tego w tytułach raportów, etykietach i nazwach plików: format(Sys.Date(), "%Y-%m-%d") tworzy nazwy, które sortują się chronologicznie. Dwa szczegóły warto znać: %d uzupełnia zerem ("August 07"), a %B/%A zwracają nazwy w języku ustawionym w systemie, więc sesja skonfigurowana po polsku wypisze "piątek" zamiast "Friday". Formatowanie zostaw na brzegach skryptu, dla ludzi; wewnątrz trzymaj daty jako Date.

Arytmetyka dat i sekwencje

Ponieważ Date to liczba dni, arytmetyka działa tak, jak można się spodziewać. Odjęcie dwóch dat daje obiekt difftime:

Z tego bloku warto wynieść trzy nawyki. Po pierwsze, owiń difftime w as.numeric(), zanim zaczniesz na nim liczyć, bo difftime niesie atrybut jednostek, który potrafi zaskoczyć w późniejszych obliczeniach. Po drugie, gdy jednostki mają znaczenie, podaj je przez difftime(units = ), zamiast przyjmować to, co wybierze R. Po trzecie, dodanie zwykłej liczby oznacza dodanie dni: w bazowym R nie ma + 1 month, bo "jeden miesiąc" nie ma stałej liczby dni.

Do kroków zgodnych z kalendarzem użyj seq(), która rozumie "day", "week", "month", "quarter" i "year":

Sekwencje miesięczne to standardowe narzędzie do okresów raportowych i podziałek osi. Jedno dziwactwo: zacznij sekwencję miesięczną 31. dnia, a R będzie liczyć prawdziwe dni przez miesiące, które go nie mają, więc pozycja "luty" wyląduje na początku marca. Zakotwicz sekwencje miesięczne na 1. dniu i wszystko inne wyprowadzaj z tego.

Wyciąganie części daty

Bazowy R ma dwie wygodne funkcje i jeden ogólny idiom. weekdays() i months() zwracają nazwy; po liczby przejdź w obie strony przez format():

Ruch format(), a potem as.integer() wygląda na okrężny, ale to standardowy idiom bazowego R i jest zwektoryzowany: przekaż mu całą kolumnę dat, a dostaniesz z powrotem całą kolumnę lat. Tego właśnie potrzebujesz po zaimportowaniu zbioru danych z datami z pliku CSV: sparsuj kolumnę dat raz przez as.Date(), a potem wyprowadź kolumny z rokiem i miesiącem do grupowania.

Gdy dni nie wystarczą: POSIXct i lubridate

Date nie zna pojęcia godzin. Gdy tylko dane mają znaczniki czasu (wpisy w logach, odczyty czujników, "zamówienie złożone o 14:32"), potrzebujesz POSIXct, klasy daty i czasu w R: sekundy od 1970 zamiast dni, z uwzględnieniem strefy czasowej.

Wszystko się przenosi: te same kody % (teraz także %H, %M, %S) działają przy parsowaniu i w format(), odejmowanie daje difftime, a Sys.time() to "teraz". Nowym obciążeniem jest strefa czasowa: przy parsowaniu podawaj tz = jawnie, bo inaczej dwie sesje w różnych strefach odczytają ten sam napis jako dwa różne momenty. I nie przechowuj danych kalendarzowych jako POSIXct "na wszelki wypadek": urodziny zapisane jako północ w jakiejś strefie mogą w innej strefie wypisać się jako poprzedni dzień, a taki błąd naprawdę ciężko wytropić. Całe dni: Date. Momenty w czasie: POSIXct.

Na koniec pakiet lubridate to przyjaźniejsza twarz, jaką większość kodu tidyverse nakłada na wszystko powyżej. Warto po niego sięgnąć, gdy mechanika bazowego R jest już jasna:

library(lubridate)

ymd("2026-08-07")            # order-based parsing: no format string
mdy("08/07/2026")            # ...you just say which order the parts come in
dmy("7 August 2026")
floor_date(Sys.Date(), "month")   # snap to the start of the period

ymd(), mdy() i dmy() zastępują przepisy formatu prostym określeniem kolejności części, a floor_date() rozwiązuje "pogrupuj te znaczniki czasu według miesięcy" jednym wywołaniem. lubridate działa na tych samych klasach Date/POSIXct pod spodem: to lepsza kierownica, a nie inny silnik.

Co warto zapamiętać

  • Date to liczba dni od 1970-01-01 przebrana tak, by wypisywać się jak data; unclass() pokazuje liczbę.
  • as.Date("2026-08-07") parsuje ISO bezpośrednio; wszystko inne wymaga przepisu format = z kodów %, a nieudane parsowanie po cichu zwraca NA.
  • format(date, "...") działa odwrotnie: te same kody, a wynikiem są napisy do wyświetlenia.
  • Odejmowanie daje difftime: ustaw units = jawnie i użyj as.numeric() przed obliczeniami. + n dodaje dni; do miesięcy użyj seq(by = "month").
  • weekdays(), months() i idiom as.integer(format(...)) wyciągają części daty w sposób zwektoryzowany.
  • Date dla całych dni, POSIXct (z jawnym tz) dla znaczników czasu; lubridate sprawia, że oba są przyjaźniejsze.

Dalej: co robić, gdy R na ciebie krzyczy, czyli czytanie komunikatów o błędach i metodyczne debugowanie.

Najczęściej zadawane pytania

Jak zamienić tekst na datę w R?

Przez as.Date(). Jeśli napis jest w formacie ISO, to po prostu działa: as.Date("2026-08-07"). Każdy inny układ wymaga przepisu format = zbudowanego z kodów %: as.Date("07/08/2026", format = "%d/%m/%Y"). Nieudane parsowanie zwraca NA, a nie błąd, więc sprawdź wynik.

Jak pobrać dzisiejszą datę w R?

Sys.Date() zwraca dzisiejszy dzień jako obiekt Date; Sys.time() zwraca bieżącą datę i godzinę jako POSIXct. Oba biorą wartość z zegara komputera i ustawień strefy czasowej.

Jak obliczyć różnicę między dwiema datami w R?

Odejmij je: as.Date("2026-08-07") - as.Date("2026-01-01") daje difftime równy 218 dni. Owiń wynik w as.numeric(), żeby użyć liczby w obliczeniach, albo wywołaj difftime(d1, d2, units = "weeks"), żeby samodzielnie wybrać jednostki, zamiast zdawać się na R.

Czym różni się Date od POSIXct w R?

Date przechowuje całe dni (wewnętrznie: liczbę dni od 1970-01-01) i nic nie wie o godzinach ani strefach czasowych. POSIXct przechowuje moment w czasie (sekundy od 1970) i uwzględnia strefę czasową. Używaj Date dla danych kalendarzowych, takich jak urodziny i terminy; POSIXct tylko wtedy, gdy liczy się pora dnia, jak w znacznikach czasu i logach.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ