使用R

时间:2017-04-26 15:33:55

标签: r dplyr

我有以下两个用户事件数据框:

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)
}

有关更快方法的任何想法吗?

3 个答案:

答案 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)

我们可以合并两个数据框,按useritem进行分组,然后在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)

我会加入useritem,假设每个用户 - 项对在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在上面的评论中提及。那些听起来很酷。