#r #sequence #dplyr
#r #последовательность #dplyr
Вопрос:
Я хочу создать инкрементную последовательность:
У меня есть фрейм данных dt <- data.table(Customer = c("a", "b", "c"), count = c(3, 4, 5), Date = c("2019-02-01","2019-05-01","2019-10-01"))
Customer count Date
1: a 3 2019-02-01
2: b 4 2019-05-01
3: c 5 2019-10-01
Я реплицирую этот фрейм данных путем подсчета, используя: dt[rep(seq(1, nrow(dt)), dt$count)]
Результат, который я получаю, является
Customer count Date
1: a 3 2019-02-01
2: a 3 2019-02-01
3: a 3 2019-02-01
4: b 4 2019-05-01
5: b 4 2019-05-01
6: b 4 2019-05-01
7: b 4 2019-05-01
8: c 5 2019-10-01
9: c 5 2019-10-01
10: c 5 2019-10-01
11: c 5 2019-10-01
12: c 5 2019-10-01
Есть ли способ добавить 3 месяца к инкрементным датам, чтобы я получил следующий результат?
Customer count Date
1: a 3 2019-02-01
2: a 3 2019-05-01
3: a 3 2019-08-01
4: b 4 2019-05-01
5: b 4 2019-08-01
6: b 4 2019-11-01
7: b 4 2020-02-01
8: c 5 2019-10-01
9: c 5 2020-01-01
10: c 5 2020-04-01
11: c 5 2020-07-01
12: c 5 2020-10-01
Я был бы признателен за любую помощь.
Спасибо
Ответ №1:
Мы можем использовать months
from lubridate
и создать seq
влияние, чтобы добавить 3 месяца в каждую строку, начиная с первого значения в каждом Customer
.
new_dt <- dt[rep(seq(1, nrow(dt)), dt$count)]
library(dplyr)
library(lubridate)
new_dt %>%
group_by(Customer) %>%
mutate(Date = as.Date(Date[1]) months(seq(0, length.out = n(), by = 3)))
# Customer count Date
# <chr> <dbl> <date>
# 1 a 3 2019-02-01
# 2 a 3 2019-05-01
# 3 a 3 2019-08-01
# 4 b 4 2019-05-01
# 5 b 4 2019-08-01
# 6 b 4 2019-11-01
# 7 b 4 2020-02-01
# 8 c 5 2019-10-01
# 9 c 5 2020-01-01
#10 c 5 2020-04-01
#11 c 5 2020-07-01
#12 c 5 2020-10-01
Та же логика может быть применена с помощью ave
with(new_dt, ave(as.Date(Date), Customer, FUN = function(x)
x[1] months(seq(0, length.out = length(x), by = 3))))
#[1] "2019-02-01" "2019-05-01" "2019-08-01" "2019-05-01" "2019-08-01" "2019-11-01"
#[7] "2020-02-01" "2019-10-01" "2020-01-01" "2020-04-01" "2020-07-01" "2020-10-01"
Ответ №2:
В базе R
с lubridate
library(lubridate)
new_dt$Date=as.Date(new_dt$Date) month(ave(new_dt$count,new_dt$Customer,FUN=function(x) cumsum(x)-x[1]))
new_dt
Customer count Date
1: a 3 2019-02-01
2: a 3 2019-02-04
3: a 3 2019-02-07
4: b 4 2019-05-01
5: b 4 2019-05-05
6: b 4 2019-05-09
7: b 4 2019-05-13
8: c 5 2019-10-01
9: c 5 2019-10-06
10: c 5 2019-10-11
11: c 5 2019-10-16
12: c 5 2019-10-21
Ответ №3:
data.table
Решение
dt[, .(count, Date = as.Date(Date) seq(0, count - 1) * months(3)), by = Customer]
# Customer count Date
# 1: a 3 2019-02-01
# 2: a 3 2019-05-01
# 3: a 3 2019-08-01
# 4: b 4 2019-05-01
# 5: b 4 2019-08-01
# 6: b 4 2019-11-01
# 7: b 4 2020-02-01
# 8: c 5 2019-10-01
# 9: c 5 2020-01-01
#10: c 5 2020-04-01
#11: c 5 2020-07-01
#12: c 5 2020-10-01