我已经问过this question
了但是现在我目前的问题略有不同,我无法使用此解决方案或弄清楚。我想要数据集2之前发生的数据集中的数据,这是我的数据:
# Dataset 1 (dts1)
UserID date Hour Events
1 5 25/07/2016 02:31 8
2 5 30/07/2016 02:42 6
3 4 23/07/2016 07:52 9
4 14 24/07/2016 03:02 5
5 17 25/07/2016 09:12 10
6 4 22/07/2016 03:22 4
和
# Dataset 2 (dts2)
UserID date Hour transactions
1 5 25/07/2016 02:29 4
2 4 24/07/2016 02:42 2
3 5 25/07/2016 02:52 3
4 6 24/07/2016 03:02 4
5 6 25/07/2016 03:12 1
6 14 26/07/2016 03:22 3
所以,我希望比较数据集1中的那些数据集,并且只添加在数据集2之前发生的数据集。换句话说,我想确保我不计算在用户的最后一次交易之后发生的那些事件。理想输出如下:
#output
UserID Events transaction
5 8 4,3
4 9,4 2
14 5 3
17 10 NA
在上面的示例中,我确保删除了用户5的事件6,因为它发生在上一次交易之后。
答案 0 :(得分:2)
我们首先将时间转换为POSIX类。
dts1$time <- strptime(paste(dts1$date, dts1$Hour), format="%d/%m/%Y %H:%M")
dts2$time <- strptime(paste(dts2$date, dts2$Hour), format="%d/%m/%Y %H:%M")
下一步是制作transactions
列。我们首先按时间排序dts2
(从最新到最早),然后使用by()
函数将dts
分组到UserID
并从每个子集中取第一行。然后,我们使用tapply
为每个transactions
检索UserID
。
dts2 <- dts2[order(dts2$time, decreasing=TRUE), ]
out <- do.call(rbind, by(dts2[,c("UserID","time")], dts2$UserID, head, 1))
out$transactions <- tapply(dts2$transactions, dts2$UserID, c)
最后,我们使用您描述的规则构建Events
列。
out$Events <- sapply(1:nrow(out), function(i) {
User2 <- out$UserID[i]
time2 <- out$time[i]
rows <- which(dts1$UserID==User2 & dts1$time<time2)
if (length(rows)>0) {
dts1$Events[rows]
} else {
NA
}
})
结果:
> out
UserID time transactions Events
4 4 2016-07-24 02:42:00 2 9, 4
5 5 2016-07-25 02:52:00 3, 4 8
6 6 2016-07-25 03:12:00 1, 4 NA
14 14 2016-07-26 03:22:00 3 5
请注意,由于用户17不在dts2
,因此它不会出现在out
中。
答案 1 :(得分:2)
这是对上一个问题的@dimitris_ps答案的修改。如果他选择回答,我很乐意删除我的。
此问题与您之前的问题之间的主要区别在于,我们现在想要针对每个特定{{1}的最后 dts1
交易之前的所有dts2
个事件}。因此,我们首先要UserID
group_by
,然后UserID
仅针对那些filter
事件时间小于上一个dts1
交易时间的行。然后我们dts2
可以summarise
和Events
,仍然按transactions
分组。
代码是:
UserID
结果是:
library(dplyr)
## I will not use the lubridate package, instead I will convert the time
## using as.POSIXct
dts1$time <- as.POSIXct(paste(dts1$date, dts1$Hour), format="%d/%m/%Y %H:%M")
dts2$time <- as.POSIXct(paste(dts2$date, dts2$Hour), format="%d/%m/%Y %H:%M")
# first join the two data.frames by UserID.
result <- left_join(dts1, dts2, by="UserID") %>%
# all subsequent processing is grouped by the UserID because we
# want to compare the last transaction time to the Event times
# for each UserID.
group_by(UserID) %>%
# apply the filtering condition dts1 Event must be before last dts2 transaction.
# Note that we keep rows for which there is no row in
# dts2 for a UserID in dts1. This is the case for UserID=17.
filter(is.na(time.y) | last(time.y) > time.x) %>%
# summarise Events and transactions
summarise(Events = toString(unique(Events)), transactions = toString(unique(transactions)))
希望这有帮助。