Rで解析:時刻データフレームを期間ごとにサブセット・フラグ付けする「timeDF」パッケージの紹介
時系列データの解析や可視化は、多くの分野において重要な作業です。特に、経済や金融などの領域では、時間を軸としたデータの分析が不可欠です。しかしながら、日付や時刻情報を含む大規模なデータセットを扱う場合、データのサブセット化や期間ごとの区分けは非常に困難な作業です。
本パッケージでは、データフレームに時刻情報を付与してtimeDFオブジェクトとして扱い、periodDFオブジェクトで定義した期間ごとにデータをサブセット化・フラグ付けすることができます。例えば、特定の期間に含まれるレコードだけを抽出したり、一定の時間間隔でデータを分割したりすることが可能です。
時刻情報を持つデータフレームを統一的に扱えるのが特徴です。期間はtime(時刻の範囲)、date(日付の範囲)、time_in_a_day(1日の中の時間帯)の3種類で用途に応じて使い分けが考えられます。
パッケージバージョンは0.9.1。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。
<おすすめのRに関する書籍です>
初心者でもすぐにできるフリー統計ソフトEZR(Easy R)で誰でも簡単統計解析(改訂第2版) | 神田善伸
Amazonで神田善伸の初心者でもすぐにできるフリー統計ソフトEZR(Easy R)で誰でも簡単統計解析(改訂第2版)。アマゾンならポイント還元本が多数。
パッケージのインストール
下記コマンドを実行してください。
# パッケージのインストール
install.packages("timeDF")
# パッケージの読み込み
library("timeDF")スポンサーリンク
コマンド例
詳細はコメント、パッケージのヘルプを確認してください。
時刻情報を持つデータフレームをtimeDFオブジェクトに変換:as.timeDFコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| df | 時刻の列を文字列として持つデータフレーム | |
| time_var | データフレーム内の時刻列の列名を指定 | “time” |
| format | 時刻の形式を指定;”as_is”を指定すると変換せずそのまま使用(列はUTCタイムゾーンのPOSIXltである必要がある) | “%Y-%m-%d %H:%M:%S” |
# 時刻データフレームを作成
time_df = data.frame(
time = c("2023-12-01 01:00:00",
"2023-12-01 02:00:00",
"2023-12-01 03:00:00",
"2023-12-01 04:00:00"),
value = c(123,
144,
150,
100)
)
# timeDFオブジェクトに変換
as.timeDF(time_df)実行結果:
time value
1 2023-12-01 01:00:00 123
2 2023-12-01 02:00:00 144
3 2023-12-01 03:00:00 150
4 2023-12-01 04:00:00 100リストにまとめられた時系列データを1つのtimeDFオブジェクトに変換:listTimeDF_to_timeDFオプション
| オプション | 意味 | 初期値 |
|---|---|---|
| listTimeDF | 時系列データのリスト | |
| name_var | 元のリストから取得した名前を保持する列名 | “name” |
# 時刻データフレームを作成
time_df = as.timeDF(
data.frame(
time = c("2024-01-01 01:00:00",
"2024-02-02 02:00:00",
"2024-03-03 03:00:00",
"2024-04-04 04:00:00",
"2024-05-05 05:00:00"),
value = c(123,
144,
150,
100,
180)
))
# 期間データフレームを作成
period_df = as.periodDF(
data.frame(
start = c(
"2024-01-01",
"2024-02-01",
"2024-03-01",
"2024-04-01",
"2024-05-01"
),
end = c(
"2024-01-31",
"2024-02-29",
"2024-03-31",
"2024-04-30",
"2024-05-31"
),
label = c(
"Jan",
"Feb",
"Mar",
"Apr",
"May"
)
),
period_type = "date",
label_var = "label"
)
# 期間ごとに時刻データフレームを抽出してリスト化
listTimeDF = extract_with_periodDF(
time_df,
period_df,
include="both")
# リストを1つのtimeDFオブジェクトにまとめる
listTimeDF_to_timeDF(listTimeDF)実行結果:
time value name
1 2024-01-01 01:00:00 123 Jan
2 2024-02-02 02:00:00 144 Feb
3 2024-03-03 03:00:00 150 Mar
4 2024-04-04 04:00:00 100 Apr
5 2024-05-05 05:00:00 180 May日付や時間の区間を表すperiodDFオブジェクトを作成:as.periodDFコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| df | 期間の定義データフレーム | |
| period_type | 指定する期間の種類を定義する要素:”time”、”date”、”time_in_a_day”のいずれか | |
| format | start・end列の日時形式を指定;”auto”の場合はperiod_typeに応じて自動選択、”as_is”の場合は変換せずそのまま使用(timeはUTCタイムゾーンのPOSIXltまたはPOSIXct、dateはDate、time_in_a_dayは0~86400の数値である必要がある) | “auto” |
| start_var | 開始日時の列名を指定 | “start” |
| end_var | 終了日時の列名を指定 | “end” |
| label_var | ラベル列名を指定 | NULL |
# 時刻の期間データフレームを作成
period_time = data.frame(
start = c("2023-12-01 01:00:00",
"2023-12-01 02:00:00",
"2023-12-01 03:00:00",
"2023-12-02 04:00:00"),
end = c("2023-12-01 02:00:00",
"2023-12-01 03:00:00",
"2023-12-01 04:00:00",
"2023-12-02 05:00:00")
)
# periodDFオブジェクトに変換
as.periodDF(period_time, "time")
# 日付の期間データフレームを作成
period_date = data.frame(
start = c("2023-01-01",
"2023-02-01",
"2023-03-01"),
end = c("2023-01-14",
"2023-02-14",
"2023-03-14"),
label = c("Jan", "Feb", "Mar")
)
# periodDFオブジェクトに変換
as.periodDF(period_date, "date")
# 1日の時間帯の期間データフレームを作成
period_time_in_a_day = data.frame(
start = c("04:00",
"11:00",
"17:00"),
end = c("11:00",
"17:00",
"24:00"),
label = c("morning",
"afternoon",
"evening")
)
# periodDFオブジェクトに変換(ラベル付き)
as.periodDF(period_time_in_a_day,
"time_in_a_day",
label_var = "label")実行結果:
# periodDFオブジェクトに変換
> as.periodDF(period_time, "time")
start end
1 2023-12-01 01:00:00 2023-12-01 02:00:00
2 2023-12-01 02:00:00 2023-12-01 03:00:00
3 2023-12-01 03:00:00 2023-12-01 04:00:00
4 2023-12-02 04:00:00 2023-12-02 05:00:00
# periodDFオブジェクトに変換
> as.periodDF(period_date, "date")
start end label
1 2023-01-01 2023-01-14 Jan
2 2023-02-01 2023-02-14 Feb
3 2023-03-01 2023-03-14 Mar
# periodDFオブジェクトに変換(ラベル付き)
> as.periodDF(period_time_in_a_day,
+ "time_in_a_day",
+ label_var = "label")
start end label
1 14400 39600 morning
2 39600 61200 afternoon
3 61200 86400 evening
指定された期間の開始と終了の時刻を要約する例:summary.periodDFコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| object | S3期間クラス |
# 期間データフレームを作成
period_time = data.frame(
start = c("2023-12-01 01:00:00",
"2023-12-01 02:00:00",
"2023-12-01 03:00:00",
"2023-12-02 04:00:00"),
end = c("2023-12-01 01:00:00",
"2023-12-01 02:00:00",
"2023-12-01 03:00:00",
"2023-12-02 04:00:00")
)
# periodDFオブジェクトに変換
periodDF = as.periodDF(period_time, "time")
# 概要を要約
summary(periodDF)実行結果:
# 概要を要約
summary(periodDF)
$class
[1] "periodDF"
$period_type
[1] "time"
$`# of rows`
[1] 4
$start_var
[1] "start"
$end_var
[1] "end"
$label_var
NULL
$`start range`
[1] "2023-12-01 01:00:00 - 2023-12-02 04:00:00"
$`end range`
[1] "2023-12-01 01:00:00 - 2023-12-02 04:00:00"
timeDFオブジェクトの概要を要約:summary.timeDFコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| object | S3時間クラス |
# 時刻データフレームを作成
time_df = data.frame(
time = c("2023-12-01 01:00:00",
"2023-12-01 02:00:00",
"2023-12-01 03:00:00",
"2023-12-02 04:00:00"),
value = c(123,
144,
150,
100)
)
# timeDFオブジェクトに変換
timeDF = as.timeDF(time_df)
# timeDFオブジェクトの概要を表示
summary(timeDF)実行結果:
# timeDFオブジェクトの概要を表示
summary(timeDF)
$class
[1] "timeDF"
$`# of rows`
[1] 4
$time_var
[1] "time"
$`time range`
[1] "2023-12-01 01:00:00 - 2023-12-02 04:00:00"特定の期間内で、指定された時間の記録を抽出:extract_with_periodDFコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| timeDF | 時系列オブジェクト | |
| periodDF | 期間オブジェクト | |
| include | 期間の両端を含めるかどうかを指定;”both”(両端)、”right”(右端のみ)、”left”(左端のみ)、”none”(含めない)のいずれか | |
| modStart | 期初に加算する値 | 0 |
| modEnd | 期末に加算する値 | 0 |
| modUnits | modStart・modEndの値の単位 | NULL |
| outputAsBool | 真偽値;TRUEの場合、返り値は抽出するレコードを表すブール値ベクトル(またはそのリスト) | FALSE |
| units | modUnitsに置き換えられる非推奨の引数 | NULL |
# 時刻データフレームを定義
time_df = data.frame(
time = c("2023-01-01 12:00:00",
"2023-01-21 12:00:00",
"2023-02-10 12:00:00",
"2023-03-02 12:00:00",
"2023-03-22 12:00:00",
"2023-04-11 12:00:00"
),
value = c(123, 144, 150, 100, 130, 145)
)
# 時刻データフレームを変換
timeDF = as.timeDF(time_df)
# 抽出範囲を指定
period_df = data.frame(
start = c("2023-01-01",
"2023-02-01",
"2023-03-01"),
end = c("2023-01-31",
"2023-02-28",
"2023-03-31"),
label = c("Jan", "Feb", "Mar")
)
# 抽出範囲をデータフレームに変換
periodDF = as.periodDF(period_df, "date", label_var = "label")
# 時刻データフレームから指定の期間で抽出
extract_with_periodDF(timeDF, periodDF, "both")実行結果:
$Jan
time value
1 2023-01-01 12:00:00 123
2 2023-01-21 12:00:00 144
$Feb
time value
3 2023-02-10 12:00:00 150
$Mar
time value
4 2023-03-02 12:00:00 100
5 2023-03-22 12:00:00 130一定間隔で区切られた時間の範囲に分割:split_timeDF_by_intervalsコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| timeDF | 時系列オブジェクト | |
| byN | 間隔の数値 | |
| byUnits | 間隔の単位:”days”、”hours”、”mins”のいずれか | |
| modStart | 間隔の始まりに加える値 | 0 |
| modEnd | 間隔の終わりに加える値 | 0 |
| modUnits | modStart・modEndの値の単位 | “auto” |
# 時刻データフレームの作成
time_df = data.frame(
time = c("2023-01-01 08:00:00",
"2023-01-01 12:00:00",
"2023-01-01 16:00:00",
"2023-01-02 08:00:00",
"2023-02-02 10:00:00",
"2023-03-03 11:00:00",
"2023-03-03 16:00:00",
"2023-03-05 12:00:00"
),
value = c(123, 144, 150, 100,
130, 145, 180, 100)
)
# 時刻データフレームに変換
timeDF = as.timeDF(time_df)
# 時刻データを日単位で分割
split_timeDF_by_intervals(timeDF, 1, "days")実行結果:
# 時刻データを日単位で分割
$`2023-01-01`
time value
1 2023-01-01 08:00:00 123
2 2023-01-01 12:00:00 144
3 2023-01-01 16:00:00 150
$`2023-01-02`
time value
4 2023-01-02 08:00:00 100
$`2023-01-03`
[1] time value
<0 rows> (or 0-length row.names)
$`2023-01-04`
[1] time value
<0 rows> (or 0-length row.names)
$`2023-01-05`
[1] time value
…(以下略)
<おすすめのRに関する書籍です>
はじめてのR: ごく初歩の操作から統計解析の導入まで | 村井 潤一郎
Amazonで村井 潤一郎のはじめてのR: ごく初歩の操作から統計解析の導入まで。
ベクトルから日付や時間の区間を表すperiodDFオブジェクトを作成:vec_to_periodDFコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| vec | 期間の始まりを表すベクトル;pre_marginが指定された場合、各期間は始まりから前方に計算 | |
| period_type | 指定する期間の種類を定義する要素:”time”、”date”、”time_in_a_day”のいずれか | |
| duration | 各期間の長さを表す数値 | |
| units | durationの単位を表す要素 | |
| format | vecの日時形式を指定;”auto”の場合はperiod_typeに応じて自動選択、”as_is”の場合は変換せずそのまま使用(timeはUTCタイムゾーンのPOSIXltまたはPOSIXct、dateはDate、time_in_a_dayは0~86400の数値である必要がある) | “auto” |
| labels | 各期間ごとの使用ラベル | NULL |
| pre_margin | 数値;指定すると、各期間がvecで指定された開始位置から前方に計算 | 0 |
# 時刻の配列を定義
start_time = c("2023-12-01 01:00:00",
"2023-12-02 02:00:00",
"2023-12-03 03:00:00",
"2023-12-04 04:00:00")
# 時刻の期間オブジェクトを作成
vec_to_periodDF(start_time, "time", 1, "hours")
# 日付の配列を定義
start_date = c("2023-01-01",
"2023-02-01",
"2023-03-01")
# 日付の期間オブジェクトを作成し、ラベルを設定
vec_to_periodDF(start_date, "date", 14, "days",
labels = c("Jan", "Feb", "Mar"))
# 1日の時間帯の配列を定義
start_time_in_a_day = c("06:00",
"11:00",
"18:00")
# 1日の時間帯の期間オブジェクトを作成し、ラベルを設定
vec_to_periodDF(start_time_in_a_day, "time_in_a_day",
4, "hours",
labels = c("morning", "afternoon", "evening"))実行結果:
# 時刻の期間オブジェクトを作成
vec_to_periodDF(start_time, "time", 1, "hours")
start end
1 2023-12-01 01:00:00 2023-12-01 02:00:00
2 2023-12-02 02:00:00 2023-12-02 03:00:00
3 2023-12-03 03:00:00 2023-12-03 04:00:00
4 2023-12-04 04:00:00 2023-12-04 05:00:00
# 日付の期間オブジェクトを作成し、ラベルを設定
vec_to_periodDF(start_date, "date", 14, "days",
labels = c("Jan", "Feb", "Mar"))
start end label
1 2023-01-01 2023-01-15 Jan
2 2023-02-01 2023-02-15 Feb
3 2023-03-01 2023-03-15 Mar
# 1日の時間帯の期間オブジェクトを作成し、ラベルを設定
vec_to_periodDF(start_time_in_a_day, "time_in_a_day",
4, "hours", labels = c("morning", "afternoon", "evening"))
start end label
1 21600 14400 morning
2 39600 14400 afternoon
3 64800 14400 evening指定された期間の開始と終了の時刻を調整:adjust_periodDFコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| periodDF | S3期間クラス | |
| adjStart | 開始に加算する値 | |
| adjEnd | 終了に加算する値 | |
| units | adjStart・adjEndの値の単位 |
# 時刻の期間データフレームを作成
period_time = data.frame(
start = c("2023-12-01 03:00:00",
"2023-12-01 20:00:00",
"2023-12-02 05:00:00",
"2023-12-03 21:00:00"),
end = c("2023-12-01 04:00:00",
"2023-12-01 21:00:00",
"2023-12-02 06:00:00",
"2023-12-03 22:00:00")
)
# periodDFオブジェクトに変換
periodTime = as.periodDF(period_time, "time")
# 開始を1時間前倒し、終了を3時間後ろ倒しに調整
adjust_periodDF(periodTime, -1, 3, units="hours")
# 日付の期間データフレームを作成
period_date = data.frame(
start = c("2023-01-01",
"2023-02-01",
"2023-03-01",
"2023-04-01"),
end = c("2023-01-14",
"2023-02-14",
"2023-03-14",
"2023-04-14"),
label = c("One", "Two", "Three", "Four")
)
# periodDFオブジェクトに変換
periodDate = as.periodDF(period_date, "date")
# 開始を1日前倒し、終了を1日後ろ倒しに調整
adjust_periodDF(periodDate, -1, 1, units="days")
# 1日の時間帯の期間データフレームを作成
period_time_in_a_day = data.frame(
start = c("04:00",
"11:00",
"17:00"),
end = c("11:00",
"17:00",
"24:00"),
label = c("morning",
"afternoon",
"evening")
)
# periodDFオブジェクトに変換(ラベル付き)
periodTimeInDay = as.periodDF(period_time_in_a_day, "time_in_a_day", label_var = "label")
# 開始・終了をそれぞれ1時間後ろ倒しに調整
adjust_periodDF(periodTimeInDay, 1, 1, "hours")実行結果:
# 開始を1時間前倒し、終了を3時間後ろ倒しに調整
adjust_periodDF(periodTime, -1, 3, units="hours")
start end
1 2023-12-01 02:00:00 2023-12-01 07:00:00
2 2023-12-01 19:00:00 2023-12-02 00:00:00
3 2023-12-02 04:00:00 2023-12-02 09:00:00
4 2023-12-03 20:00:00 2023-12-04 01:00:00
# 開始を1日前倒し、終了を1日後ろ倒しに調整
adjust_periodDF(periodDate, -1, 1, units="days")
start end label
1 2022-12-31 2023-01-15 One
2 2023-01-31 2023-02-15 Two
3 2023-02-28 2023-03-15 Three
4 2023-03-31 2023-04-15 Four
# 開始・終了をそれぞれ1時間後ろ倒しに調整
adjust_periodDF(periodTimeInDay, 1, 1, "hours")
start end label
1 18000 43200 morning
2 43200 64800 afternoon
3 64800 86400 evening
31 0 3600 evening
この記事が誰かの役に立ちますように。
スポンサーリンク