为数据框中不存在的观测值添加行带有日期

问题描述

我对以下格式的数据有一个简单的问题(date是dd / m / yy)。问题下方是用于数据输入的代码

#>      date  a  b
#> 1 25/1/20 10 20
#> 2 26/1/20 20 40

如何添加一月的所有行,其中ab的值为0?

我想要的输出是:

#>      date  a  b
#> 1 01/1/20  0  0
#> 2 02/1/20  0  0
#> ...
#> ...
#>   25/1/20 10 20
#>   26/1/20 20 40

首选Tidyverse答案,但我对任何解决方案都很满意。

数据输入代码

df <- data.frame(
  stringsAsFactors = FALSE,date = c("25/1/20","26/1/20"),a = c(10L,20L),b = c(20L,40L)
)

解决方法

您可以使用新的数据框,然后再加入。关键是根据df上的最长日期创建一个新的数据框,并定义自第一天起的顺序。这里的代码:

library(dplyr)
library(lubridate)
#Data
df <- data.frame(
  stringsAsFactors = FALSE,date = c("25/1/20","26/1/20"),a = c(10L,20L),b = c(20L,40L)
)
#Code 1
df %>% mutate(date=dmy(date)) -> df
#Identify max date
maxdate <- max(df$date)
#Set initial day
startday <- as.Date(paste0(format(maxdate,'%Y-%m'),'-01'))
#New data frame
ndf <- data.frame(date=seq(startday,maxdate,by=1))
#Join
ndf %>% left_join(df) %>% replace(is.na(.),0)

输出:

         date  a  b
1  2020-01-01  0  0
2  2020-01-02  0  0
3  2020-01-03  0  0
4  2020-01-04  0  0
5  2020-01-05  0  0
6  2020-01-06  0  0
7  2020-01-07  0  0
8  2020-01-08  0  0
9  2020-01-09  0  0
10 2020-01-10  0  0
11 2020-01-11  0  0
12 2020-01-12  0  0
13 2020-01-13  0  0
14 2020-01-14  0  0
15 2020-01-15  0  0
16 2020-01-16  0  0
17 2020-01-17  0  0
18 2020-01-18  0  0
19 2020-01-19  0  0
20 2020-01-20  0  0
21 2020-01-21  0  0
22 2020-01-22  0  0
23 2020-01-23  0  0
24 2020-01-24  0  0
25 2020-01-25 10 20
26 2020-01-26 20 40
,

将“日期”转换为complete类后,我们可以在tidyverse中使用Date

library(dplyr)
library(tidyr)
library(lubridate)
df %>% 
   mutate(date = dmy(date)) %>% 
   complete(date = seq(floor_date(min(date),'month'),max(date),by = 'day'),fill = list(a = 0,b = 0))
# A tibble: 26 x 3
#   date           a     b
#   <date>     <dbl> <dbl>
# 1 2020-01-01     0     0
# 2 2020-01-02     0     0
# 3 2020-01-03     0     0
# 4 2020-01-04     0     0
# 5 2020-01-05     0     0
# 6 2020-01-06     0     0
# 7 2020-01-07     0     0
# 8 2020-01-08     0     0
# 9 2020-01-09     0     0
#10 2020-01-10     0     0
# … with 16 more rows