私のデータでは、いくつかのIDの観測がいくつかの月に存在し、他の観測は存在しません。
_dat <- data.frame(c(1, 1, 1, 2, 3, 3, 3, 4, 4, 4), c(rep(30, 2), rep(25, 5), rep(20, 3)), c('2017-01-01', '2017-02-01', '2017-04-01', '2017-02-01', '2017-01-01', '2017-02-01', '2017-03-01', '2017-01-01',
'2017-02-01', '2017-04-01'))
colnames(dat) <- c('id', 'value', 'date')
_
id
の値ごとに、そのid
の欠けている月とNA
のvalue
が欠けている月を含む行を挿入します。
seq(min(as.Date(dat$date)), max(as.Date(dat$date)), by = 'months')
ですべての月にこれを(ある程度)簡潔に行う方法はありますか?私はよくtidyverseとdata.tableを使用しますが、どのようなアプローチでも受け入れます。
tidyr::complete()
欠損値を埋めます列としてid
とdate
を追加します(...
)展開する
library(tidyverse)
complete(dat, id, date)
# A tibble: 16 x 3
id date value
<dbl> <date> <dbl>
1 1.00 2017-01-01 30.0
2 1.00 2017-02-01 30.0
3 1.00 2017-03-01 NA
4 1.00 2017-04-01 25.0
5 2.00 2017-01-01 NA
6 2.00 2017-02-01 25.0
7 2.00 2017-03-01 NA
8 2.00 2017-04-01 NA
9 3.00 2017-01-01 25.0
10 3.00 2017-02-01 25.0
11 3.00 2017-03-01 25.0
12 3.00 2017-04-01 NA
13 4.00 2017-01-01 20.0
14 4.00 2017-02-01 20.0
15 4.00 2017-03-01 NA
16 4.00 2017-04-01 20.0
tidyr::complete()
は、サンプルデータを指定すると機能します。
library(tidyverse)
dat %>%
group_by(id) %>%
complete(date) %>%
ungroup()
id date value
<dbl> <fct> <dbl>
1 1.00 2017-01-01 30.0
2 1.00 2017-02-01 30.0
3 1.00 2017-03-01 NA
4 1.00 2017-04-01 25.0
5 2.00 2017-01-01 NA
6 2.00 2017-02-01 25.0
7 2.00 2017-03-01 NA
8 2.00 2017-04-01 NA
9 3.00 2017-01-01 25.0
10 3.00 2017-02-01 25.0
11 3.00 2017-03-01 25.0
12 3.00 2017-04-01 NA
13 4.00 2017-01-01 20.0
14 4.00 2017-02-01 20.0
15 4.00 2017-03-01 NA
16 4.00 2017-04-01 20.0
expand.grid
とmerge
を使用してこれを行う方法を次に示します。
dat <- data.frame(c(1, 1, 1, 2, 3, 3, 3, 4, 4, 4), c(rep(30, 2), rep(25, 5), rep(20, 3)), as.Date(c('2017-01-01', '2017-02-01', '2017-04-01', '2017-02-01', '2017-01-01', '2017-02-01', '2017-03-01', '2017-01-01',
'2017-02-01', '2017-04-01')))
colnames(dat) <- c('id', 'value', 'date')
date_range <- seq(min(as.Date(dat$date)), max(as.Date(dat$date)), by = 'months')
dat_expanded <- expand.grid(date_range, dat$id)
colnames(dat_expanded) <- c("date", "id")
result <- merge(dat, dat_expanded, by=c("id", "date"), all.y = T)