日付・時間関数Tips大全
Rには日付(date)オブジェクトを表すクラス "Date" と,日付時分秒(date-time)オブジェクトを表すクラス "POSIXlt", "POSIXct" がある.
クラス "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" (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() は二つの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"
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)」と呼ばれる,ある起点日付からの正負の経過日数で表す流儀が普通である.日付・時間専用の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に変換