# 展开不同单位的时间序列

##### 问题描述投票：3回答：2

``````   id       date     type
1   1 2019-06-16  1_month
2   1 2019-07-16  1_month
3   1 2019-08-08  1_month
4   1 2019-09-04 3_months
5   2 2019-01-23  1_month
6   2 2019-05-05  1_month
7   2 2019-07-10 3_months
8   3 2019-07-02  1_month
9   3 2020-04-18 3_months
10  4 2019-03-10  1_month
11  4 2019-04-08  1_month

library(tidyverse)

df <- data.frame(stringsAsFactors=FALSE,
id = c(1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4),
date = c("2019-06-16", "2019-07-16", "2019-08-08", "2019-09-04",
"2019-01-23", "2019-05-05", "2019-07-10",
"2019-07-02", "2020-04-18", "2019-03-10", "2019-04-08"),
type = c("1_month", "1_month", "1_month", "3_months", "1_month",
"1_month", "3_months", "1_month", "3_months",
"1_month", "1_month")
)
``````

[对于每个ID，有一些条目“ 1_month”-也就是每月长度-和“ 3_months”条目。

``````df_r <- data.frame(stringsAsFactors=FALSE,
id = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3),
date = c("2019-06-16", "2019-07-16", "2019-08-08", "2019-09-04",
"2019-10-04", "2019-11-03", "2019-01-23",
"2019-05-05", "2019-07-10", "2019-08-09", "2019-09-08",
"2019-07-02", "2020-04-18", "2020-05-18", "2020-06-17"),
type = c("1_month", "1_month", "1_month", "1_month", "1_month",
"1_month", "1_month", "1_month", "1_month", "1_month",
"1_month", "1_month", "1_month", "1_month", "1_month")
)

id       date    type
1   1 2019-06-16 1_month
2   1 2019-07-16 1_month
3   1 2019-08-08 1_month
4   1 2019-09-04 1_month
5   1 2019-10-04 1_month
6   1 2019-11-03 1_month
7   2 2019-01-23 1_month
8   2 2019-05-05 1_month
9   2 2019-07-10 1_month
10  2 2019-08-09 1_month
11  2 2019-09-08 1_month
12  3 2019-07-02 1_month
13  3 2020-04-18 1_month
14  3 2020-05-18 1_month
15  3 2020-06-17 1_month
``````

• 首先隔离3个月的条目
• 对于它们每个，按user_id分组，然后按如下所示使用`complete`

``````df %>%
filter(type == '3_months') %>%
group_by(id) %>%
complete(id, date = seq(date, by = "30 days", length.out = 3))
``````

``````Error in seq.default(date, by = "30 days", length.out = 3) :
'from' must be a finite number
``````

r dplyr time-series tidyverse
##### 2个回答
0

``````library(tidyverse)
library(lubridate)

df <- data.frame(stringsAsFactors=FALSE,
id = c(1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4),
date = c("2019-06-16", "2019-07-16", "2019-08-08", "2019-09-04",
"2019-01-23", "2019-05-05", "2019-07-10",
"2019-07-02", "2020-04-18", "2019-03-10", "2019-04-08"),
type = c("1_month", "1_month", "1_month", "3_months", "1_month",
"1_month", "3_months", "1_month", "3_months",
"1_month", "1_month")
)

df %>%
as_tibble() %>%
separate(type, into = c("number", "date_type")) %>%
mutate(
number = as.numeric(number),
date = as_date(date)
) %>%
rowwise() %>%
mutate(
date_end = date %m+% months(number - 1),
date_seq = list(seq.Date(date, date_end, by = "1 month"))
) %>%
unnest(date_seq)
#> # A tibble: 17 x 6
#>       id date       number date_type date_end   date_seq
#>    <dbl> <date>      <dbl> <chr>     <date>     <date>
#>  1     1 2019-06-16      1 month     2019-06-16 2019-06-16
#>  2     1 2019-07-16      1 month     2019-07-16 2019-07-16
#>  3     1 2019-08-08      1 month     2019-08-08 2019-08-08
#>  4     1 2019-09-04      3 months    2019-11-04 2019-09-04
#>  5     1 2019-09-04      3 months    2019-11-04 2019-10-04
#>  6     1 2019-09-04      3 months    2019-11-04 2019-11-04
#>  7     2 2019-01-23      1 month     2019-01-23 2019-01-23
#>  8     2 2019-05-05      1 month     2019-05-05 2019-05-05
#>  9     2 2019-07-10      3 months    2019-09-10 2019-07-10
#> 10     2 2019-07-10      3 months    2019-09-10 2019-08-10
#> 11     2 2019-07-10      3 months    2019-09-10 2019-09-10
#> 12     3 2019-07-02      1 month     2019-07-02 2019-07-02
#> 13     3 2020-04-18      3 months    2020-06-18 2020-04-18
#> 14     3 2020-04-18      3 months    2020-06-18 2020-05-18
#> 15     3 2020-04-18      3 months    2020-06-18 2020-06-18
#> 16     4 2019-03-10      1 month     2019-03-10 2019-03-10
#> 17     4 2019-04-08      1 month     2019-04-08 2019-04-08
``````

reprex package（v0.3.0）在2020-05-11创建

0

``````library(tidyverse)
library(lubridate)

df2 <- df %>%
mutate(type2 = as.integer(str_replace(type, "_month\$|_months\$", ""))) %>%
mutate(date = ymd(date)) %>%
mutate(dates = map2(date, type2, function(x, y){
seq_num <- 0:(y - 1)
date_seq <- map_chr(seq_num, function(i) as.character(x + days(i * 30)))
return(date_seq)
})) %>%
select(id, date = dates) %>%
unnest(cols = date) %>%
mutate(type = "1_month")
df2
# # A tibble: 17 x 3
#       id date       type
#    <dbl> <chr>      <chr>
#  1     1 2019-06-16 1_month
#  2     1 2019-07-16 1_month
#  3     1 2019-08-08 1_month
#  4     1 2019-09-04 1_month
#  5     1 2019-10-04 1_month
#  6     1 2019-11-03 1_month
#  7     2 2019-01-23 1_month
#  8     2 2019-05-05 1_month
#  9     2 2019-07-10 1_month
# 10     2 2019-08-09 1_month
# 11     2 2019-09-08 1_month
# 12     3 2019-07-02 1_month
# 13     3 2020-04-18 1_month
# 14     3 2020-05-18 1_month
# 15     3 2020-06-17 1_month
# 16     4 2019-03-10 1_month
# 17     4 2019-04-08 1_month
``````