我有以下两个用户事件数据框:
data.favorite(用户在时收藏项 )
user item time event
1 1 A 2 fav
2 1 B 6 fav
3 2 D 9 fav
4 3 A 5 fav
data.view(用户在时间查看项目)
user item time event
1 1 A 1 view
2 1 A 3 view
3 1 B 4 view
4 1 B 5 view
5 1 B 7 view
6 1 C 8 view
7 3 A 2 view
8 3 A 9 view
我现在只想保留那些用户收藏该项后发生的data.view事件。例如。 data.view的第1行将被删除,因为用户1在2处收藏了项目A.然而,时间3处的视图事件将保留,因为用户已经在该点处收藏了该项目。因此,此示例的结果应如下所示:
user item time event
1 1 A 3 view
2 1 B 7 view
3 3 A 9 view
我目前的做法太慢了。我将自定义函数应用于data.view:
wasFav = function(u, i, t) {
favs = data.favorite %>% filter(user == u, item == i, time < t)
return(nrow(favs) > 0)
}
有关更快方法的任何想法吗?
答案 0 :(得分:1)
将match
与data.frames一起使用,名为data.view和data.fav:
#Find indices of matching users&items
Indices <- match(paste(data.view$user, data.view$item), paste(data.fav$user, data.fav$item))
#add corresponding fav time to data.view:
data.view$favtime <- data.fav$time[Indices]
#only keep rows in which time is greater than fav.time:
data.view <- data.view[data.view$time>data.view$favtime & !is.na(data.view$favtime),]
答案 1 :(得分:1)
我们可以合并两个数据框,按user
和item
进行分组,然后在event
之后仅保留data.view
fav
行。我们使用cumsum
来计算fav
的实例,并从fav
的第一个实例中选择所有行。
第一组代码用于说明,因此您可以看到该方法正在执行的操作。第二组代码直接进行过滤。
library(tidyverse)
data.favorite %>% bind_rows(data.view) %>%
arrange(user, item, time) %>%
group_by(user, item) %>%
mutate(sequence = cumsum(event=="fav"))
user item time event sequence 1 1 A 1 view 0 2 1 A 2 fav 1 3 1 A 3 view 1 4 1 B 4 view 0 5 1 B 5 view 0 6 1 B 6 fav 1 7 1 B 7 view 1 8 1 C 8 view 0 9 2 D 9 fav 1 10 3 A 2 view 0 11 3 A 5 fav 1 12 3 A 9 view 1
data.favorite %>% bind_rows(data.view) %>%
arrange(user, item, time) %>%
group_by(user, item) %>%
filter(cumsum(event=="fav") >= 1, event=="view")
user item time event 1 1 A 3 view 2 1 B 7 view 3 3 A 9 view
答案 2 :(得分:1)
我会加入user
和item
,假设每个用户 - 项对在data.favorite中只出现一次。然后,您可以直接将查看时间与项目受欢迎的时间进行比较,并丢弃所有time_viewed&lt; time_favorited:
data.view %>%
left_join(data.favorite, by=c("user", "item"), suffix=c("_view","_fav")) %>%
filter(time_view > time_fav)
ETA:那是在我了解非平等联盟之前的事情。 @Henrik在上面的评论中提及。那些听起来很酷。