日付情報を含むデータの編集方法についての備忘録。
1 サンプルデータ作成
以下のようなサンプルデータ(100万件)を用意する。
- date : 日付情報(YYYY-mm-dd形式)
- sex : 性別 (Male | Female)
- age : 年齢
このサンプルデータはコロナウィルス感染者情報のようなデータをイメージしている。
library(tidyverse)
library(lubridate)
x <- seq.Date(from=ymd('2022/1/1'), to=ymd('2023/12/31'), by='day')
size <- 1e6
### サンプルデータ作成
(f <- tibble(
date=sample(
x, size=size, replace=TRUE,
prob=dnorm(0:(length(x)-1), mean=length(x)/2, sd=360)
),
sex=sample(
as.factor(c("Male", "Female")), size=size, replace=TRUE
),
age=sample(
0:120, size=size, replace=TRUE,
prob=dnorm(0:120, mean=50, sd=12)
)
))
## # A tibble: 1,000,000 × 3
## date sex age
## <date> <fct> <int>
## 1 2023-01-07 Female 65
## 2 2023-10-01 Male 38
## 3 2022-07-03 Female 21
## 4 2022-08-18 Female 32
## 5 2023-01-28 Female 30
## 6 2023-06-12 Female 40
## 7 2022-02-21 Male 59
## 8 2022-11-04 Male 59
## 9 2023-08-26 Female 58
## 10 2022-11-06 Male 35
## # … with 999,990 more rows
2 日付単位に集計する
サンプルデータを月単位、四半期毎に集計したい場合がある。この時に役に立つのが dplyr::count()
と lubridate::floor_date()
関数だ。
この関数はdate-timeオブジェクトの切り下げをしてくれる。切り下げる単位はunit
で指定することができる。unit
に指定できるキーワードは ‘second’, ‘minute’, ‘hour’, ‘day’, ‘week’, ‘month’, ‘bimonth’, ‘quarter’, ‘season’, ‘halfyear’, ’year’である。
2.1 月毎集計
(m1 <- f %>% count(date=floor_date(date, unit='month')))
## # A tibble: 24 × 2
## date n
## <date> <int>
## 1 2022-01-01 30988
## 2 2022-02-01 30411
## 3 2022-03-01 36084
## 4 2022-04-01 36886
## 5 2022-05-01 40681
## 6 2022-06-01 40937
## 7 2022-07-01 44938
## 8 2022-08-01 46297
## 9 2022-09-01 45799
## 10 2022-10-01 48739
## # … with 14 more rows
ggplot(data=m1) +
aes(x=date, y=n) +
geom_col(alpha=0.7) +
scale_x_date(date_labels='%Y-%m')
2.2 四半期毎集計
(q1 <- f %>% count(date=floor_date(date, unit='quarter')))
## # A tibble: 8 × 2
## date n
## <date> <int>
## 1 2022-01-01 97483
## 2 2022-04-01 118504
## 3 2022-07-01 137034
## 4 2022-10-01 147193
## 5 2023-01-01 143190
## 6 2023-04-01 136268
## 7 2023-07-01 120621
## 8 2023-10-01 99707
ggplot(data=q1) +
aes(x=date, y=n) +
geom_col(alpha=0.7) +
scale_x_date(date_labels='%Y-%m')
2.3 半期毎集計
(h1 <- f %>% count(date=floor_date(date, unit='halfyear')))
## # A tibble: 4 × 2
## date n
## <date> <int>
## 1 2022-01-01 215987
## 2 2022-07-01 284227
## 3 2023-01-01 279458
## 4 2023-07-01 220328
ggplot(data=h1) +
aes(x=date, y=n) +
geom_col(alpha=0.7) +
scale_x_date(date_labels='%Y-%m')
2.4 年毎集計
(y1 <- f %>% count(date=floor_date(date, unit='year')))
## # A tibble: 2 × 2
## date n
## <date> <int>
## 1 2022-01-01 500214
## 2 2023-01-01 499786
ggplot(data=y1) +
aes(x=date, y=n) +
geom_col(alpha=0.7) +
scale_x_date(date_labels='%Y', date_breaks='1 years')
3 年代別に集計する
サンプルデータを年代別に集計するには dplyr::count()
と dplyr::case_when()
関数を使う。
(a1 <- f %>%
mutate(
age2=case_when(
age < 10 ~ "000~009歳",
age < 20 ~ "010~019歳",
age < 30 ~ "020~029歳",
age < 40 ~ "030~039歳",
age < 50 ~ "040~049歳",
age < 60 ~ "050~059歳",
age < 70 ~ "060~069歳",
age < 80 ~ "070~079歳",
age < 90 ~ "080~089歳",
age < 100 ~ "090~099歳",
age < 999 ~ "100~歳",
TRUE ~ "その他"
)
)
)
## # A tibble: 1,000,000 × 4
## date sex age age2
## <date> <fct> <int> <chr>
## 1 2023-01-07 Female 65 060~069歳
## 2 2023-10-01 Male 38 030~039歳
## 3 2022-07-03 Female 21 020~029歳
## 4 2022-08-18 Female 32 030~039歳
## 5 2023-01-28 Female 30 030~039歳
## 6 2023-06-12 Female 40 040~049歳
## 7 2022-02-21 Male 59 050~059歳
## 8 2022-11-04 Male 59 050~059歳
## 9 2023-08-26 Female 58 050~059歳
## 10 2022-11-06 Male 35 030~039歳
## # … with 999,990 more rows
(a1 <- a1 %>% count(age2))
## # A tibble: 11 × 2
## age2 n
## <chr> <int>
## 1 000~009歳 357
## 2 010~019歳 5131
## 3 020~029歳 38492
## 4 030~039歳 146958
## 5 040~049歳 292607
## 6 050~059歳 302126
## 7 060~069歳 162312
## 8 070~079歳 45045
## 9 080~089歳 6470
## 10 090~099歳 492
## 11 100~歳 10
ggplot(data=a1) +
aes(x=fct_rev(age2), y=n) +
geom_col(alpha=0.7) +
coord_flip() +
labs(x=NULL, y=NULL)
4 組み合わせる
サンプルデータを月別、男女別に集計する。
f %>%
count(date=floor_date(date, unit='month'), sex) %>%
ggplot() +
aes(x=date, y=n, fill=sex) +
geom_col(alpha=0.7) +
facet_grid(rows=vars(sex)) +
scale_x_date(date_labels='%Y-%m') +
labs(x=NULL, y=NULL) +
guides(fill='none')