日付・時間関数Tips大全

Rには日付(date)オブジェクトを表すクラス "Date" と,日付時分秒(date-time)オブジェクトを表すクラス "POSIXlt", "POSIXct" がある.

クラス "Date"

クラス "Date" は date オブジェクト(年月日)を表し,1970-01-01 以来の経過日数(負の値は過去に遡る)で表現される.内部的には実数で表現されるが,表示の際は整数値とされる.日数との加減算,比較演算が可能である.format(), plot(), hist(), seq(), cut(), round() 関数は"Date" クラス用のメソッド関数を持つ.as.Date() は数値を "Date" オブジェクトに変換する.weekdays(), months() はそれぞれ曜日と月を返す.

> (today <- Sys.Date())                      # 現在の日付
[1] "2007-06-02"                             # 表示の際は整形される
> str(today)                                 # 1970/1/1以来の経過日数値で表現されている
Class 'Date'  num 13666
> start <- 0; class(start) <- "Date"; start  # 起点年月日
[1] "1970-01-01"
> format(today, "%d %b %Y")                  # 月数を文字で表示
[1] "02  6月 2007"
> (weeks <- seq(today, len=5, by="1 week"))  # 次の5日
[1] "2007-06-02" "2007-06-09" "2007-06-16" "2007-06-23" "2007-06-30"
> weekdays(today)                            # 曜日
[1] "土曜日"
> months(weeks)                              # 月 
[1] "6月" "6月" "6月" "6月" "6月"
> as.Date(.leap.seconds)                     # 閏秒
[1] "1972-07-01" "1973-01-01" "1974-01-01" "1975-01-01" "1976-01-01"
      (以下略)
> (z <- Sys.Date())
[1] "2007-06-02"
> z + 10                                     # 10日後
[1] "2007-06-12"
> z < c("2006-06-01", "2007-01-01", "2010-01-01")  # 大小比較
[1] FALSE FALSE  TRUE

クラス "POSIXct", "POSIXlt","POSIXt"

年月日時分秒を表すクラスには "POSIXct" (1970年元旦からの符号付き経過秒)と,名前ラベル

  'sec' 0-61: 秒                            'min'  0-59: 分
 'hour' 0-23: 時                            'mday' 1-31: (一月中の)日
  'mon' 0-11: 月                            'year' 1900年からの経過年数
 'wday' 0-6:  一週中の日,日曜日から始まる  'yday' 0-365: 一年の間の日
'isdst' サマータイム(daylight saving time)フラグ.正は有効,0は無効,負は不明

を持つ文字列リストである "POSIXlt" の2種類がある.それぞれ ANSI C の "calendar time" (time-t データタイプ) と "local time" (struct tm データタイプ) に基づき,名前もそれらに由来する.クラス "POSIXt" は両者を含むクラスである."POSIXct" オブジェクトはデータフレーム中で使うのにより便利であるが,"POSIXlt" オブジェクトはより可読性が高い.オブジェクト同士の論理比較演算と,限定された算術演算(時間差を加減する)が定義されている.data-time オブジェクト同士の差には difftime() 関数が使われる.その際,"POSIXlt" オブジェクトはタイムゾーンを明示しない限り,現在のタイムゾーンが使われることに注意しよう.date-time オブジェクトの操作はタイムゾーン(サマータイムの有無を含む)と閏秒(これまで計23日)の存在によりかなり複雑になり,システムによっては不完全になる可能性がある.特にLinuxを含むUnix風システムでは,タイムゾーン環境変数 "TZ" を正しく設定する必要がある.date-time オブジェクトは環境変数 TZ から決まる属性 "tzone" をしばしば持つことがある.

> (z <- Sys.time())                          # 現在の時間,クラス"POSIXct"オブジェクト
[1] "2007-05-31 21:30:45 JST"
> str(z)
'POSIXct', format: chr "2007-05-31 21:38:07"
> z - 3600                                   # 一時間前
[1] "2007-05-31 21:30:45 JST"
> as.POSIXlt(Sys.time(), "GMT")              # GMTでの現在の時間
[1] "2007-05-31 12:38:07 GMT"
> print(.leap.seconds)                       # 日本標準時での全ての閏秒
[1] "1972-07-01 09:00:00" "1973-01-01 09:00:00" "1974-01-01 09:00:00"
(途中略)
[22] "1999-01-01 09:00:00" "2006-01-01 09:00:00"
> print(.leap.seconds, tz="PST8PDT")         # Seattle標準時では
[1] "1972-06-30 17:00:00 PDT" "1972-12-31 16:00:00 PST"
(途中略)
[23] "2005-12-31 16:00:00 PST"

時間差 difftime()

関数 difftime() は二つのdateもしくはdate-timeオブジェクトの差分を計算する. 結果はクラス "difftime",時間単位を表す属性 units (units()関数で操作できる)を持つ. date-timeオブジェクト同士の差はこの関数をオプション units="auto" で呼び出す. 関数 as.difftime() は数値もしくは時間差の文字列表現を "difftime" オブジェクトに変換する. "difftime" オブジェクトに対しては限定された算術演算(加減,スカラ−による乗除算)と,比較演算が可能である.

書式:  time1 - time2
       difftime(time1, time2, tz = "",
                units = c("auto", "secs", "mins", "hours", "days", "weeks"))
       as.difftime(time, format = "%X", units="auto")
       units(x),  units(x) <- value
引数: time1,time2,time date, もしくは date-time オブジェクト
                    tz タイムゾーン.""は現在のタイムゾーンを表す
                 units 時間単位を表す文字列        
> (z <- Sys.time() - 3600)
[1] "2007-06-02 06:35:26 JST"
> Sys.time() - z                              # 丁度3600秒
Time difference of 1.000018 hours
> ISOdate(2001, 4, 26) - ISOdate(2001, 2, 26) # R1.2.2とR1.2.3のリリース期間差
Time difference of 59 days
> as.difftime(c("0:3:20", "11:23:15"))        # 時間を文字列で与える
Time differences in mins
[1]   3.333333 683.250000
attr(,"tzone")
[1] ""
> (z <- as.difftime(c(0,30,60), units="mins")) 秒,分,時間単位での表示.
Time differences in mins
[1]  0 30 60
> as.numeric(z, units="secs")
[1]    0 1800 3600
> as.numeric(z, units="hours")
[1] 0.0 0.5 1.0
> format(z)
[1] " 0 mins" "30 mins" "60 mins"

date-timeクラスオブジェクトと文字列間の変換

format(), as.character(), strftime() は date-time オブジェクトを文字列ベクトルに変換する.strptime() は逆に文字列を "POSIXlt" クラスオブジェクトに変換する.strftime() は format.POSIXlt() の別名である.変換はタイムゾーンに依存する.ISOdatetime() と ISOdate() は strptime() 関数のラッパ関数であり,既定値だけが異なる.サマータイムの開始と終了に伴い,存在しない時間,二度登場する時間があることに注意しよう.これらの関数はタイムゾーンを指定する引数 tz や,書式引数 format を持つ(ISO C/POSIX 標準に従う).詳細はhelp(ISOdate) を参照.

> format(Sys.time(), "%a %b %d %X %Y %Z")        # date()関数のロケール依存版
[1] "土  6月 02 07時42分03秒 2007 JST"
> format(Sys.time(), "%H:%M:%OS3")               # 0.1秒単位の表示(OSがサポートすれば)
[1] "07:42:03.220"
> dates <- c("02/27/92", "02/27/92", "01/14/92") # 書式'm/d/y h:m:s'使用例     
> times <- c("23:03:20", "22:29:56", "01:03:30")
> strptime(paste(dates, times), "%m/%d/%y %H:%M:%S")
[1] "1992-02-27 23:03:20" "1992-02-27 22:29:56" "1992-01-14 01:03:30"

ジュリアン通日 (Julian date)

計算機による日付の処理では「ジュリアン通日(Julian date)」と呼ばれる,ある起点日付からの正負の経過日数で表す流儀が普通である.日付・時間専用のRパッケージ date にはジュリアン通日を年月日形式に変換する date.mmddyyyy() 関数がある.注意すべきは

> date.mmddyyyy(0)           # dateパッケージの起点年月日
[1] "1/1/1960"

と起点年月日が異なること.Unix界では 1970/1/1/0:00:00} からの経過秒数で年月日時分秒を表す慣習があり,POSIX規約はこれを継承している.一方 SAS では 1960/1/1 からの経過日数を使い,date パッケージはこれを継承している.Julian date を扱うときは,まず起点年月日そして時刻を確認する必要がある.なお,年月日をどういう順序で並べるかも国により微妙に違い.ロケール(言語や国・地域ごとに異なる単位,記号,日付,通貨などの表記規則の集合) で決められている.

注:ジュリアン通日とは,本来 BC 4713/1/1 の正午を起点とする主に天文学で使われる日付計算用の単位で,1583年に Joseph Justus Scaliger により,ユリウス暦,グレゴリオ暦双方での日付の変換や,日数計算のために提案され,天文学者ジョン・ハーシェルがその著書で使って以来広まった.通説では Julian とは Scaliger の父親の名前に由来し,ユリウス暦の Julius(つまりシーザー)とは無関係である.

タイムゾーン

当然だが,同じ日付・時間でもタイムゾーンにより異なる.異なったタイムゾーンでの日付・時間データを扱うときはこの点に注意が必要になる."POSIXlt" オブジェクトはタイムゾーンを表すタイム属性 "tzone" を持つ.

> ( z <- Sys.time() )
[1] "2007-06-03 22:32:06 JST"
> attributes(z)
$class
[1] "POSIXt"  "POSIXct"           # POSIXctオブジェクト,タイムゾーン属性は無い
> ( zz <- as.POSIXlt(z, "GMT") )  # POSIXltオブジェクトに変換,タイムゾーンはGMT
[1] "2007-06-03 13:32:06 GMT"
> attributes(zz)
$names
[1] "sec"   "min"   "hour"  "mday"  "mon"   "year"  "wday"  "yday"  "isdst"
$class
[1] "POSIXt"  "POSIXlt"
$tzone                             # タイムゾーン属性が付け加わる
[1] "GMT"
> (zzz <- as.POSIXlt(zz, "JST"))   # タイムゾーンをJSTに戻す ※少なくとも2.13.2ではunknown timezoneとされるので、Asia/Tokyoを入力
[1] "2007-06-03 13:32:06 GMT"      # タイムゾーンは依然GMTのまま
> attributes(zzz)
$names
[1] "sec"   "min"   "hour"  "mday"  "mon"   "year"  "wday"  "yday"  "isdst"
$class
[1] "POSIXt"  "POSIXlt"
$tzone
[1] "GMT"
> (zzzz <- as.POSIXct(zz, "JST"))  # POSIXctオブジェクトへ,タイムゾーンはJST
[1] "2007-06-03 13:32:06 JST"
> attributes(zzzz)
$class
[1] "POSIXt"  "POSIXct"
$tzone
[1] "JST"                          # タイムゾーン属性JSTが付く

連続する日付の生成

> seq(as.Date("2010-07-31"), as.Date("2010-08-10"), by="days")
 [1] "2010-07-31" "2010-08-01" "2010-08-02" "2010-08-03" "2010-08-04"
 [6] "2010-08-05" "2010-08-06" "2010-08-07" "2010-08-08" "2010-08-09"
[11] "2010-08-10"

既出でした

> library(chron)
> seq.dates("05/03/2002", "05/08/2002")
[1] 05/03/02 05/04/02 05/05/02 05/06/02 05/07/02 05/08/02

月日の順序はアメリカ式とイギリス式とか。文字列にしたいなら,as.character()

日付・時間用のパッケージ

Rの貢献パッケージには chron, date, fCalendar といった日付・時間専用のパッケージがある。例えば、パッケージの date には次の関数がある.

as.date        データをdateオブジェクトに強制変換
date.ddmmmyy   Julian dateを/dd/mm/yy形式に整形
date.mdy       Julian dateを月日年(曜日)文字列リストに変換
date.mmddyy    Julian dateをmm/dd/yy 形式に整形
date.mmddyyyy  Julian dateをmm/dd/yyyy 形式に整形
is.date        Dateオブジェクト検査
mdy.date       Julian dateに変換

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2023-03-25 (土) 11:19:16