データ分析メモと北欧生活

旧Untitled Note. データ分析、計量経済・統計とR、水産管理、英語勉強、海外生活などについて備忘録や自分の勉強のOutputの場所として

MENU

【R】整頓されてない時系列のデータから、一日前だけのラグを作りたい。

これ賢いやん、と思った簡単なテクニックを見つけたのでメモ。

問題

一部の日付が抜けているようなデータ(アンバランスドパネル)で、一日前のラグを作りたいが、日付が抜けているところは飛ばしたい。
lag()を使うと、一日以上前のデータのラグを作ってしまう。

解決策

別で、一日前のデータを作り、joinでメインのデータに統合する。

コード

たとえばこんなデータがあるとする。

data = data.frame(
  date = c("2020-01-01","2020-01-02","2020-01-03","2020-01-04","2020-01-01","2020-01-02","2020-01-03","2020-01-04"),
  company = c("A","A","A","A","B","B","B","B"),
  price = runif(8,100,200)
) %>%
  slice(-7) %>%
  mutate(date = ymd(date))
> data
        date company    price
1 2020-01-01       A 192.4453
2 2020-01-02       A 159.0478
3 2020-01-03       A 124.5317
4 2020-01-04       A 198.5095
5 2020-01-01       B 136.7652
6 2020-01-02       B 120.0669
7 2020-01-04       B 108.4874

データを見ると、companyのBのうち、1月3日のデータが抜けているのがわかる。
仮にpriceのラグのデータを作りたいとするが、一日前のラグのデータがほしいのであって、そのままlag()でデータを作ると、Bの1月4日のラグは1月2日のデータになってしまう。

そこで、別で一日先のデータを作り、統合する。

# 一日先のデータ、dateに一日足して、priceを別の変数名を移したあと、priceを消す。
prev_days = data %>%
  mutate(date = date + 1, lag_price = price, price = NULL)

# データをdateとcompanyで統合する。
data2 = data %>%
  left_join(prev_days, by = c("date","company"))

すると、きれいに1月4日のラグは抜けた状態でラグを作ることができる。

> data2
        date company    price lag_price
1 2020-01-01       A 171.8838        NA
2 2020-01-02       A 187.0172  171.8838
3 2020-01-03       A 141.1960  187.0172
4 2020-01-04       A 148.3973  141.1960
5 2020-01-01       B 180.0195        NA
6 2020-01-02       B 182.1140  180.0195
7 2020-01-04       B 140.9689        NA


このアイデアを応用すれば、整頓されてない時系列からいろんなパターンのラグデータを作ることができそうである。

もとのアイデアは以下のポストから。
data.table - Create lagged variable in unbalanced panel data in R - Stack Overflow


もう少し発展して、過去n日間の合計値を計算したい、などの場合は「前処理大全」に載ってますね。
データを扱う際は必携の書として手元に置いてます。