按组填补缺失日期

19

在我的数据中,对于某些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缺失的月份和valueNA值。

是否有一种方法可以(比较)简洁地对seq(min(as.Date(dat$date)),max(as.Date(dat$date)),by ='months')中的所有月份执行此操作? 我经常使用tidyverse和data.table,但也可以使用其他方法。


3
这是您需要的吗? https://dev59.com/V1YO5IYBdhLWcg3wPvNv这篇文章介绍了如何使用 tidyverse 中的工具填补分组时间序列中缺失的日期。 - thelatemail
3个回答

23

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

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

2
这个方法是可行的,但比必要的复杂。你可以在complete中简单地提供iddate作为需要扩展的列,避免分组和取消分组。 - Rich Pauloo

2

以下是使用 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)

为避免dat_expanded中的重复行,您应该使用以下代码:dat_expanded <- expand.grid(date_range, unique(dat$id)) - user131476

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接