在R的数据框中插入带有零的行

Luc*_*s E 2 row r zero dataframe

考虑像这样的零散数据集:

   ID       Date Value
1   1 2012-01-01  5065
4   1 2012-01-04  1508
5   1 2012-01-05  9489
6   1 2012-01-06  7613
7   2 2012-01-07  6896
8   2 2012-01-08  2643
11  3 2012-01-02  7294
12  3 2012-01-03  8726
13  3 2012-01-04  6262
14  3 2012-01-05  2999
15  3 2012-01-06 10000
16  3 2012-01-07  1405
18  3 2012-01-09  8372
Run Code Online (Sandbox Code Playgroud)

请注意,缺少(2,3,9,10,17)的观察值。我想要的是用“ Value” = 0填充数据集中的某些空白,如下所示:

   ID       Date Value
1   1 2012-01-01  5920
2   1 2012-01-02     0
3   1 2012-01-03     0
4   1 2012-01-04  8377
5   1 2012-01-05  7810
6   1 2012-01-06  6452
7   2 2012-01-07  3483
8   2 2012-01-08  5426
9   2 2012-01-09     0
11  3 2012-01-02  7854
12  3 2012-01-03  1948
13  3 2012-01-04  7141
14  3 2012-01-05  5402
15  3 2012-01-06  6412
16  3 2012-01-07  7043
17  3 2012-01-08     0
18  3 2012-01-09  3270
Run Code Online (Sandbox Code Playgroud)

关键是,只有在过去观察到相同(分组)ID时,才应插入零。我希望避免任何循环,因为整个数据集非常大。

有什么建议么?要重现数据帧:

df <- data.frame(matrix(0, nrow = 18, ncol = 3,
                  dimnames = list(NULL, c("ID","Date","Value"))) )
df[,1] = c(1,1,1,1,1,1,2,2,2,3,3,3,3,3,3,3,3,3) 
df[,2] = seq(as.Date("2012-01-01"),
             as.Date("2012-01-9"), 
             by=1)
df[,3] = sample(1000:10000,18,replace=T)
df = df[-c(2,3,9,10,17),]
Run Code Online (Sandbox Code Playgroud)

Mak*_*212 5

Tidyverse拥有complete一种扩展此类内容的简便方法。我们还可以在同一步骤中使用fill参数将替换NAs为零。

library(tidyverse)

df %>% group_by(ID) %>% 
  complete(Date = seq(min(Date), max(Date), "day"), fill = list(Value = 0)) 

# A tibble: 16 x 3
# Groups:   ID [3]
      ID Date       Value
   <dbl> <date>     <dbl>
 1     1 2012-01-01  1047
 2     1 2012-01-02     0
 3     1 2012-01-03     0
 4     1 2012-01-04  8147
 5     1 2012-01-05  1359
 6     1 2012-01-06  1892
 7     2 2012-01-07  3362
 8     2 2012-01-08  8988
 9     3 2012-01-02  2731
10     3 2012-01-03  9794

...
Run Code Online (Sandbox Code Playgroud)