Одна основная стратегия c:
split()
фрейм данных от клиента - в каждом фрейме данных, удалите строки, которые слишком далеко от даты преобразования с
lapply()
- соедините фрейм данных вместе - я буду использовать
do.call
с rbind()
, но есть и другие возможные варианты
Вот стратегия в действии (это переписанная версия, которая правильно обрабатывает случаи, когда на одного покупателя приходится более одной конверсии, поскольку я не знал, было ли это важно для вас):
df <- data.frame(
Sessionid = 1:13,
Clientid = c(rep(1, 6), 2, 2, rep(3, 4), 4),
Date = as.Date(c("01-01-2020", "02-01-2020", "03-01-2020", "15-02-2020",
"16-02-2020", "17-02-2020", "01-01-2020", "02-01-2020",
"01-05-2020", "15-06-2020", "01-08-2020", "02-08-2020",
"02-03-2020"),
"%d-%m-%y"),
Conversion = c(rep("No", 5), "Yes", "No", "Yes", "No", "Yes", "No", "Yes", "No")
) # expanded toy data set meant to demonstrate cases with multiple / no conversions
df
# Sessionid Clientid Date Conversion
# 1 1 1 2020-01-01 No
# 2 2 1 2020-01-02 No
# 3 3 1 2020-01-03 No
# 4 4 1 2020-02-15 No
# 5 5 1 2020-02-16 No
# 6 6 1 2020-02-17 Yes
# 7 7 2 2020-01-01 No
# 8 8 2 2020-01-02 Yes
# 9 9 3 2020-05-01 No
# 10 10 3 2020-06-15 Yes
# 11 11 3 2020-08-01 No
# 12 12 3 2020-08-02 Yes
# 13 13 4 2020-03-02 No
step1 <- split(df, df$Clientid)
# break df into a list of data frames according to Clientid
step2 <- lapply(step1, function(x) {
daterange <- x[x$Conversion == "Yes", ]$Date
# record set of successful conversion dates
daterange <- unlist(lapply(daterange, function(y) seq(y-30, y+30, by = "days")))
# puff out set of days by 30 days in either direction from each conversion
x[x$Date %in% daterange, ]
# subset each data frame by keeping only those with a date in the range
})
df2 <- do.call("rbind", step2)
# glue the list of data frames back together
row.names(df2) <- NULL
# remove junk artifact row names
df2
# Sessionid Clientid Date Conversion
# 1 4 1 2020-02-15 No
# 2 5 1 2020-02-16 No
# 3 6 1 2020-02-17 Yes
# 4 7 2 2020-01-01 No
# 5 8 2 2020-01-02 Yes
# 6 10 3 2020-06-15 Yes
# 7 11 3 2020-08-01 No
# 8 12 3 2020-08-02 Yes