[Stata][time data]Stataでの時間、日付データの扱いについて

clear glass with red sand grainer stata
Photo by Pixabay on Pexels.com

Stata

統計解析ソフト Stata | ライトストーン
統計解析ソフトStataの紹介ページです。計量経済データ/臨床データなどの解析に利用できます。

https://www.stata.com/manuals13/u24.pdf

Stataは時間の扱いについては割と出来が悪いイメージがあったが、完全に自分の落ち度であった。上記リンクの二番目のドキュメントをしっかりと理解すれば、Stataの時間データは何も怖くない。

Stataのデータ形式

Stataで用いられるデータ形式は”21nov2006″という形になっている。時刻は”13:42:02:213″という形で、合わせると”21nov2006 13:42:02:213″になる。これを”11/21/2005″や”November 21, 2006″、時間を”1:42 p.m.”と表記することももちろん可能である。Stataは時刻を整数型として記録するので、最初の型が上記のいずれであっても、相互の変換が可能である。

Stataの時間データの開始年月は”01Jan1960″、つまり1960年の1月1日0時0分000秒になる。つまり、”01jan1960 00:00:00.000″である。これに整数0を当てている。整数1は”01jan1960 00:00:00.001″であり、整数-1は”31dec1959 23:59:59.999″となる。この論理でいくと、例えば”21nov2006″は整数1,479,735,722,213となる。ここで、うるう秒を無視している。うるう秒を考慮すると、23秒後の1,479,735,745,213という表記にある。Stataはどちらの方法でも動作する。

重要なことは、Stataは1960年の1月1日0時0分000秒を基準として、整数で日時を管理しているということである。なので、例えば午後2時というのは、午前0時を基準として14時間で、これをミリ秒(\(10^3\)秒)に直すと$$14\times 60\times 60\times 1000 = 50,400,000$$となる。この原理を理解しておけば、怖いことはない。例えば、

start_time end_time
21aug2021 21nov2022
22aug2021 22nov2022

などという変数があったとき、引き算して

gen(erate) diff = end_time - start_time

を作ると大きい数字がでてきて一瞬思考が停止してしまう。これは、時間に直したかったら最初から

gen(erate) diff = (end_time - start_time)/3,600,000

としておけば良い。

うるう秒を無視する時間と考慮する時間

うるう秒を無視する場合、%tc変数と呼び、うるう秒を考慮する場合は、Cを大文字にして%tC変数という。その他の%変数を以下の表に示す。

フォーマット基準時間単位コメント
%tc01jan1960ミリ秒うるう秒を無視する
%tC01jan1960ミリ秒うるう秒を考慮
%td01jan1960カレンダー時間
%tw1960-w152週目は7日以上になる
%tmjan1960カレンダーの月時間
%tq1960-q1四半期会計四半期
%th1960-h1半年2四半期
%ty0 A.D1960は1960年を意味する
%tbユーザー定義
Stataの%tフォーマット

時間データの入力

上記の表に対応して、以下のような入力を行う。

フォーマット文字から数値への変換関数
%tcclock(string, mask)
%tCclock(string, mask)
%tddate(string, mask)
%twweekly(string, mask)
%tmmonthly(string, mask)
%tqquarterly(string, mask)
%thhalfyearly(string, mask)
%tyyearly(string, mask)
文字変数から%t変数への変換

関数の詳細については下記の関連リンク参照。上記で、”string“は文字列で、”mask“というのは日や時間のデータの順序を指定する。例えば、%tdのmaskとしては”M”, “D”, “Y”がある。

date(string, "DMY")

上のように”DMY”とすると、「日、月、年」の順で文字列を指定したことになる。つまり、”21nov2006″, “”21 November 2006”, “21-11-2006″あるいは”21111206″のような文字列を時間データとして読み取れる。同様に、

date(string, "MDY")

は”November 21, 2006″, “11/21/2006”, “11212006”といった形式の文字列を時間データとして読み取る。

date(string, "MD19Y")

年が2桁の場合、上のように”Y”の前に19や20をつける。こうすると”Feb. 15 ’98”, “2/15/98”, “21598”なども読み取れる。こちらも詳細については下記の関連リンクを参照。

具体例

ここではいくつか具体的な用法が例示されている。一つを実際に行ってみる。

use http://www.stata-press.com/data/r13/datexmpl2, replace

以下のようなデータセットをimportする。

具体例で手を動かす。

変数”timestamp”はよくありそうであるが、このままでは時間データとして扱いにくい。そこで”clock”関数の登場である。clock関数のmaskでは”D”, “M”, “Y”の他”h”, “m”, “s”も用いられる。これらは順に「日」、「月」、「年」、「時間」、「分」、「秒」を表す。clock関数を理解するため、次の変数を作る。ちなみに、” “のスペースは必要。

gen str ts = substr(timestamp, 5, 15) + " " + substr(timestamp, 25, 4)
list ts

次のような変数”ts”が生成される。なお、substrは以下のような使い方で、

substr(var, a, b)

変数”var”のa文字目からb文字をとる、という意味になる。

変数”ts”が生成される。

この変数はまだ文字型なので、clock関数で時間データに変換する。

gen double dt = clock(ts, "MD hms Y")

Stataの時間データは比較的大きい整数になるので、doubleを指定しておく。dtはまだ時間データではなく、以下のような(大きい)整数である。

“dt”はまだ時間データでない。

これをformatして、%tcデータにする。

format dt %tc
無事に人が読み取りやすい時間データに。

これは時間データで人間が見やすいが、数値として扱うことも可能で、以下の例がわかりやすい。

sort dt
gen hours = hours(dt-df[_n-1])
format hours %9.2f

まずdtをsortしておいてから、前の項との差を作っている。差を作っているので、初項は欠損値になる。

前項との差を作っている。

最後のformatは桁の調整である。

関連記事

時間の扱い

関連リンク

上記の基本を抑えておけば、Stataの時間データについてはかなりの応用が効くと思う。より詳細については、以下のドキュメントも参照。

https://www.stata.com/manuals13/ddatetime.pdf#ddatetime

コメント

タイトルとURLをコピーしました