R の Date は衣装をまとった日数カウンタ
文字列を本物の日付に変えるには as.Date() を、今日を取得するには Sys.Date() を使います。どちらの背後にも単純な仕掛けがあります。R の Date クラスは単なる数値 — 1970 年 1 月 1 日からの日数 — に、カレンダー上の日付のように表示させる衣装を着せたものです。その衣装は unclass() で脱がせられます。
この 20672 が生の日数カウントであり、このページの他のすべてを成り立たせているものです。比較も引き算も連続生成も、下では単なる整数演算にすぎません。衣装はそれを 使いやすく するためのものです。同じ数値が日付として表示され、日付として書式化され、日付軸にプロットされます。
as.Date() は ISO 形式の "YYYY-MM-DD" を何の助けもなく解析します。これはファイル内で日付をその形式で保存すべき理由のひとつです。早めに身につけるべき習慣がひとつあります。解析に失敗すると、エラーではなく静かに NA が返るので、新しいものを解析した後は必ず結果に目を通しましょう。
日付に 見えるだけ の文字列は、依然としてただの文字列です。"2026-08-07" < "2026-11-01" がたまたま正しく比較されるのは ISO の順序がアルファベット順と一致するからで、"07/08/2026" はでたらめに並びます。まず変換してから比較しましょう。
format = で他の並びを解析する
世界は ISO の日付では書きません。それ以外のすべてに対して、as.Date() は format = 引数を受け取ります。これは % コードで組み立てた、入力文字列を記述するレシピです。
3 つとも同じ日に解析されます。レシピは区切り文字も含めて文字列と完全に一致していなければなりません。"%d/%m/%Y" は "07-08-2026" を解析できません。実際に使うコードは次のとおりです。
| コード | 意味 | 例 |
|---|---|---|
%Y | 4 桁の年 | 2026 |
%y | 2 桁の年 | 26 |
%m | 月の番号 | 08 |
%d | 日 | 07 |
%b | 月名の略称 | Aug |
%B | 月名の正式名 | August |
%a | 曜日の略称 | Fri |
%A | 曜日の正式名 | Friday |
%H | 時 (00-23) | 14 |
%M | 分 | 30 |
%S | 秒 | 05 |
典型的な待ち伏せが "07/08/2026" そのものです。世界の多くでは日/月/年、米国では月/日/年であり、あなたのファイルがどちらを意味するのか R には推測できません。さらに悪いことに、間違った推測でもたいてい「動いて」しまいます。どちらの読み方でも有効な日付になるからです。そしてある月の 13 日が現れたとき初めて NA に解析されます(13 月は存在しません)。レシピを書く前に、データの慣習を把握しておきましょう。
出力用に日付を書式設定する
format() は as.Date() の鏡像です。同じ % コードを逆方向に走らせます。入力は Date、出力は文字列です。
これはレポートのタイトル、ラベル、ファイル名に使います。format(Sys.Date(), "%Y-%m-%d") は時系列順に並ぶ名前を作ります。知っておくべき点が 2 つあります。%d はゼロ埋めします("August 07")。そして %B/%A はシステムの言語設定に従った名前を生成します。ドイツ語に設定されたセッションでは "Friday" ではなく "Freitag" が表示されます。書式設定は人間向けにスクリプトの端で行い、内部では日付は Date のままにしておきましょう。
日付の演算と連続生成
Date は日数カウントなので、演算は期待どおりに動きます。2 つの日付を引き算すると difftime オブジェクトが得られます。
このブロックから持ち帰るべき習慣が 3 つあります。第一に、difftime を計算に使う前に as.numeric() で包むこと。difftime は単位の属性を持っており、後の計算で驚かされることがあります。第二に、単位が重要なときは R が選んだものを受け入れるのではなく difftime(units = ) で明示すること。第三に、素の数値を足すのは 日 を足すことを意味します。base R には + 1 か月 は存在しません。「1 か月」は固定の日数ではないからです。
カレンダーを意識したステップには seq() を使います。"day"、"week"、"month"、"quarter"、"year" を理解します。
月単位の連続生成は、レポート期間や軸の目盛りを作る標準的な道具です。ひとつ癖があります。31 日から月単位の連続生成を始めると、R はその日が存在しない月でも実際の日数を数え続けるため、「2 月」に当たる要素が 3 月初めに着地します。月単位の連続生成は 1 日を起点にして、他のものはそこから導出しましょう。
日付の一部を取り出す
base R には便利な抽出関数が 2 つと、汎用のイディオムが 1 つあります。weekdays() と months() は名前を返し、数値が欲しいときは format() を経由します。
format() してから as.integer() という流れは回りくどく見えますが、これが base R の標準的なイディオムであり、ベクトル化されています。日付の列をまるごと渡せば、年の列がまるごと返ってきます。日付を含むデータセットを CSV ファイルから読み込んだ後にまさに必要になるのがこれです。日付列を as.Date() で一度だけ解析し、そこからグループ化用の年や月の列を導出します。
日単位では足りないとき: POSIXct と lubridate
Date には時刻の概念がありません。データにタイムスタンプが現れた瞬間 — ログのエントリ、センサーの測定値、「14:32 に発注」 — R の日 時 クラスである POSIXct が必要になります。日数ではなく 1970 年からの秒数を保持し、タイムゾーンを認識します。
すべてが引き継がれます。同じ % コード(今度は %H、%M、%S も含みます)が解析と format() に使え、引き算は difftime を返し、Sys.time() が「今」です。新たに背負う負担はタイムゾーンです。解析時には tz = を明示的に渡してください。そうしないと、異なるゾーンにある 2 つのセッションが同じ文字列を別々の瞬間として読み取ってしまいます。また、「念のため」にカレンダーデータを POSIXct で保存するのは避けましょう。あるゾーンの深夜として保存された誕生日は、別のゾーンでは前日として表示されることがあり、追跡が本当に苦痛なバグになります。丸一日なら Date、瞬間なら POSIXct です。
最後に、lubridate パッケージは、多くの tidyverse コードが上記すべてにかぶせている、より親しみやすい顔です。base の仕組みを理解したら採用する価値があります。
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()、dmy() は書式のレシピを「どの順序で並んでいるか」という単純な指定に置き換え、floor_date() は「これらのタイムスタンプを月ごとにグループ化する」を 1 回の呼び出しで解決します。lubridate は内部で同じ Date/POSIXct クラスに乗っています。別のエンジンではなく、より良いハンドルです。
この章のまとめ
Dateは 1970-01-01 からの日数カウントに、日付らしく表示される装いを着せたものです。unclass()でその数値が見えます。as.Date("2026-08-07")は ISO をそのまま解析します。それ以外には%コードによるformat =のレシピが必要で、解析失敗時は静かにNAが返ります。format(date, "...")はその逆で、同じコードを使って表示用の文字列を生成します。- 引き算は difftime を返します。
units =を明示的に指定し、計算前にas.numeric()しましょう。+ nは日を足します。月単位にはseq(by = "month")を使います。 weekdays()、months()、そしてas.integer(format(...))のイディオムで、ベクトル化された形で部分を取り出せます。- 丸一日には
Date、タイムスタンプには(tzを明示した)POSIXctを。lubridate はどちらも扱いやすくします。
次は、R に叱られたときにどうするか — エラーメッセージの読み方と、体系的なデバッグの方法です。
よくある質問
R で文字列を日付に変換するにはどうしますか?
as.Date() を使います。文字列が ISO 形式ならそのまま動きます: as.Date("2026-08-07")。それ以外の並びには % コードで組み立てた format = のレシピが必要です: as.Date("07/08/2026", format = "%d/%m/%Y")。解析に失敗するとエラーではなく NA が返るので、結果を必ず確認してください。
R で今日の日付を取得するにはどうしますか?
Sys.Date() は今日を Date オブジェクトとして返し、Sys.time() は現在の日時を POSIXct として返します。どちらもコンピュータの時計とタイムゾーン設定に基づきます。
R で 2 つの日付の差を計算するにはどうしますか?
引き算します: as.Date("2026-08-07") - as.Date("2026-01-01") は 218 日の difftime を返します。数値として計算に使うなら as.numeric() で包み、単位を R に任せず自分で選びたいなら difftime(d1, d2, units = "weeks") を呼びます。
R の Date と POSIXct の違いは何ですか?
Date は日単位(内部的には 1970-01-01 からの日数)を保持し、時刻やタイムゾーンについては何も知りません。POSIXct は時間上の瞬間(1970 年からの秒数)を保持し、タイムゾーンを認識します。誕生日や締切のようなカレンダーデータには Date を、タイムスタンプやログのように時刻が重要な場合にだけ POSIXct を使いましょう。