web-dev-qa-db-ja.com

R-欠落している日付をグループで埋める

私のデータでは、いくつかの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の欠けている月とNAvalueが欠けている月を含む行を挿入します。

seq(min(as.Date(dat$date)), max(as.Date(dat$date)), by = 'months')ですべての月にこれを(ある程度)簡潔に行う方法はありますか?私はよくtidyverseとdata.tableを使用しますが、どのようなアプローチでも受け入れます。

9
kathystehl

tidyr::complete()欠損値を埋めます

列としてiddateを追加します(...)展開する

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
10
Rich Pauloo

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
3
neilfws

expand.gridmergeを使用してこれを行う方法を次に示します。

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)
1
efbbrown