R:将隐式缺失值和组填充到数据的整个时间跨度

R: Fill in Implicit Missing Values and Groups to the Entire Time Span of the Data

Objective: 在数据的整个时间跨度内为每个 ID 和每个 填充隐式缺失值,包括完全缺失的 来自数据集。

背景: 每个 ID 都有几个组,每个组都应该有每天的值。但是,某些值缺少某些日期(例如 1b 2019-01-01),并且某些组在数据集中完全缺失(例如 2b)。

# A tibble: 8 x 4
     ID group date       value
  <dbl> <chr> <chr>      <dbl>
1     1 a     2019-01-01     1
2     1 a     2019-01-02     3
3     1 a     2019-01-03     4
4     1 b     2019-01-02     4
5     1 b     2019-01-03     5
6     2 a     2019-01-01     8
7     2 a     2019-01-02     9
8     2 a     2019-01-03     1

生成数据帧的代码

df <- tibble(ID = c(1, 1, 1, 1, 1, 2, 2, 2),
             group = c('a', 'a', 'a', 'b', 'b', 'a', 'a', 'a'),
             date = c('2019-01-01', '2019-01-02','2019-01-03', '2019-01-02', '2019-01-03', '2019-01-01', '2019-01-02', '2019-01-03'),
             value = c(1, 3, 4, 4, 5, 8, 9, 1))

尝试 1:

library(tsibble)
df %>% 
  # tsibble format
  as_tsibble(key = c(ID, group), index = date) %>%
  # group by
  group_by(ID, group) %>%
  # fill gaps
  fill_gaps(.full = TRUE)

尝试 2:

library(tidyverse)
complete(df, expand(df, nesting(ID, group), date = full_seq(date,1)))

两者产生相同的结果:请注意 组 2b 缺失

# A tsibble: 9 x 4 [1D]
# Key:       ID, group [3]
# Groups:    ID, group [3]
     ID group date       value
  <dbl> <chr> <date>     <dbl>
1     1 a     2019-01-01     1
2     1 a     2019-01-02     3
3     1 a     2019-01-03     4
4     1 b     2019-01-01    NA
5     1 b     2019-01-02     4
6     1 b     2019-01-03     5
7     2 a     2019-01-01     8
8     2 a     2019-01-02     9
9     2 a     2019-01-03     1

我希望输出是

# A tibble: 12 x 4
      ID group date       value
   <dbl> <chr> <chr>      <dbl>
 1     1 a     2019-01-01     1
 2     1 a     2019-01-02     3
 3     1 a     2019-01-03     4
 4     1 b     2019-01-01     NA
 5     1 b     2019-01-02     4
 6     1 b     2019-01-03     5
 7     2 a     2019-01-01     8
 8     2 a     2019-01-02     9
 9     2 a     2019-01-03     1
10     2 b     2019-01-01     NA
11     2 b     2019-01-02     NA
12     2 b     2019-01-03     NA

其中 组 b从数据集中隐式缺失,出现在结果中。

请注意,我的数据集有 800 万行,并且每天都在增长。该代码将每天执行,所以我真的很期待 快速 和执行任务的便捷方式。但欢迎任何想法或答案!

您可以创建一个数据框,其中包含 ID、组和日期的唯一值的笛卡尔积,然后将其与原始数据框合并以获得所需的结果。

zz <- merge(merge(unique(df$ID), unique(df$group), by = NULL, all = TRUE), 
            unique(df$date), by = NULL, all = TRUE)
merge(df, zz, by.x = c('ID','group', 'date'), by.y = c('x','y.x', 'y.y'), all = TRUE)

当然,如果您有大量组件和日期,它会很昂贵。在这种情况下,您可以首先将 ID/group 组合与您的原始数据框合并以获得仅缺失的组合,然后将其与日期集合并,如果您明白我的意思,则再次仅选择缺失的组合。

实际上您的第二次尝试非常接近您的预期,但需要将 nesting() 替换为 crossing()nesting() 仅查找数据中出现的组合,但 crossing() 查找所有可能的组合。

library(tidyr)
df <- tibble(ID = c(1, 1, 1, 1, 1, 2, 2, 2),
             group = c('a', 'a', 'a', 'b', 'b', 'a', 'a', 'a'),
             date = as.Date(c('2019-01-01', '2019-01-02','2019-01-03', '2019-01-02', '2019-01-03', '2019-01-01', '2019-01-02', '2019-01-03')),
             value = c(1, 3, 4, 4, 5, 8, 9, 1))
complete(df, expand(df, crossing(ID, group), date = full_seq(date, 1)))
#> # A tibble: 12 x 4
#>       ID group date       value
#>    <dbl> <chr> <date>     <dbl>
#>  1     1 a     2019-01-01     1
#>  2     1 a     2019-01-02     3
#>  3     1 a     2019-01-03     4
#>  4     1 b     2019-01-01    NA
#>  5     1 b     2019-01-02     4
#>  6     1 b     2019-01-03     5
#>  7     2 a     2019-01-01     8
#>  8     2 a     2019-01-02     9
#>  9     2 a     2019-01-03     1
#> 10     2 b     2019-01-01    NA
#> 11     2 b     2019-01-02    NA
#> 12     2 b     2019-01-03    NA

reprex package (v0.3.0)

于 2019-10-13 创建