df
是一个数据框,显示不同客户的访问次数和购买时间。
id<-c(1,1,1,1,1,1,2,2,2,2,2)
visit<-rep("yes",11)
purchase<-c("2015-04-27 13:57:06","2015-04-27 13:59:19","2015-04-27 14:03:35","NA","NA","2015-04-27 16:59:42","2015-05-18 17:01:09","2015-05-18 17:03:40","2015-05-18 17:04:00","NA","NA")
df<-data.frame(id,visit,purchase)
当purchase
变量为NA
时,表示客户已访问过该网站但未进行购买。
现在我需要创建一个名为time.gap
的新变量来计算每个客户购买之间的时间差距,如下所示:
id visit purchase time.gap
1 1 yes 2015-04-27 13:57:06 NA
2 1 yes 2015-04-27 13:59:19 133
3 1 yes 2015-04-27 14:03:35 256
4 1 yes NA NA
5 1 yes NA NA
6 1 yes 2015-04-27 16:59:42 10567
7 2 yes 2015-05-18 17:01:09 NA
8 2 yes 2015-05-18 17:03:40 151
9 2 yes 2015-05-18 17:04:00 20
10 2 yes NA NA
11 2 yes NA NA
非常感谢您的帮助
答案 0 :(得分:1)
我说每个用户ID的时间间隔需要一个额外的步骤,在ID级别进行分组。
-EDITED错过了日期转换。
使用dplyr
lubridate和zoo
# libraries
library(dplyr)
library(zoo)
library(lubridate)
# the data
id<-c(1,1,1,1,1,1,2,2,2,2,2)
visit<-rep("yes",11)
purchase<-c("2015-04-27 13:57:06","2015-04-27 13:59:19","2015-04-27 14:03:35","NA","NA","2015-04-27 16:59:42","2015-05-18 17:01:09","2015-05-18 17:03:40","2015-05-18 17:04:00","NA","NA")
df<-data.frame(id,visit,purchase)
df$purchase <- lubridate::ymd_hms(df$purchase)
# helper column
df$purch <- zoo::na.locf(df$purchase)
df
#> df
# id visit purchase purch
#1 1 yes 2015-04-27 13:57:06 2015-04-27 13:57:06
#2 1 yes 2015-04-27 13:59:19 2015-04-27 13:59:19
#3 1 yes 2015-04-27 14:03:35 2015-04-27 14:03:35
#4 1 yes <NA> 2015-04-27 14:03:35
#5 1 yes <NA> 2015-04-27 14:03:35
#6 1 yes 2015-04-27 16:59:42 2015-04-27 16:59:42
#7 2 yes 2015-05-18 17:01:09 2015-05-18 17:01:09
#8 2 yes 2015-05-18 17:03:40 2015-05-18 17:03:40
#9 2 yes 2015-05-18 17:04:00 2015-05-18 17:04:00
#10 2 yes <NA> 2015-05-18 17:04:00
#11 2 yes <NA> 2015-05-18 17:04:00
# run it
df%>%
group_by(id)%>%
mutate(dif=c(NA, diff(purch)))%>%
select(-purch)
#Source: local data frame [11 x 4]
#Groups: id
#
# id visit purchase dif
#1 1 yes 2015-04-27 13:57:06 NA
#2 1 yes 2015-04-27 13:59:19 133
#3 1 yes 2015-04-27 14:03:35 256
#4 1 yes <NA> 0
#5 1 yes <NA> 0
#6 1 yes 2015-04-27 16:59:42 10567
#7 2 yes 2015-05-18 17:01:09 NA
#8 2 yes 2015-05-18 17:03:40 151
#9 2 yes 2015-05-18 17:04:00 20
#10 2 yes <NA> 0
#11 2 yes <NA> 0
或一次性
df%>%
mutate(purch=zoo::na.locf(lubridate::ymd_hms(df$purchase))) %>%
group_by(id) %>%
mutate(dif=c(NA, diff(purch))) %>%
select(-purch)
# packages [1] lubridate_1.3.3 zoo_1.7-12 dplyr_0.4.2
答案 1 :(得分:1)
df$purchase <- strptime(df$purchase, "%Y-%m-%d %H:%M:%S")
df1 <- df
library(dplyr)
df %>%
filter(!is.na(purchase)) %>%
group_by(id) %>%
mutate(time.gap = c(NA, difftime(purchase[-1],
purchase[-length(purchase)], units="secs"))) %>%
left_join(df1, .)
# id visit purchase time.gap
# 1 1 yes 2015-04-27 13:57:06 NA
# 2 1 yes 2015-04-27 13:59:19 133
# 3 1 yes 2015-04-27 14:03:35 256
# 4 1 yes <NA> NA
# 5 1 yes <NA> NA
# 6 1 yes 2015-04-27 16:59:42 10567
# 7 2 yes 2015-05-18 17:01:09 NA
# 8 2 yes 2015-05-18 17:03:40 151
# 9 2 yes 2015-05-18 17:04:00 20
# 10 2 yes <NA> NA
# 11 2 yes <NA> NA
这是dplyr
方法,其中添加了合并。difftime
使用而不是diff
,因为它允许单位参数。
数据强>
id<-c(1,1,1,1,1,1,2,2,2,2,2)
visit<-rep("yes",11)
purchase<-c("2015-04-27 13:57:06","2015-04-27 13:59:19","2015-04-27 14:03:35","NA","NA","2015-04-27 16:59:42","2015-05-18 17:01:09","2015-05-18 17:03:40","2015-05-18 17:04:00","NA","NA")
df<-data.frame(id,visit,purchase)
is.na(df$purchase) <- df$purchase == "NA"
df$purchase <- as.POSIXct(df$purchase)
<强>疑难解答强>
如果您的实际数据遇到问题,我们可以通过测试来确定问题的来源:
s <- split(df, df$id)
test <- list()
for(i in 1:length(s)) {
s1 <- s[[i]]
test[[i]] <- s[[i]] %>%
filter(!is.na(purchase)) %>%
group_by(id) %>%
mutate(time.gap = c(NA, difftime(purchase[-1],
purchase[-length(purchase)], units="secs"))) %>%
left_join(s1, .)
}
现在test
是包含代码所有迭代的列表。如果抛出错误,我们将知道它发生的位置,因为所有其他成功的运行都将被保存。因此,如果我收到错误并查看test
并且其所有ID都为3
,那么我知道ID 4
导致错误。