在按某个变量分组的两个不同数据帧中查找两组的交集

Finding inteserction of two sets within two different dataframes grouping by some var

我有这两个数据框:

setA:

   session_id            datetime request
        <int>              <dttm>   <dbl>
1        1105 2016-03-09 00:33:42       8
2        1105 2016-03-09 00:33:43       3
3        1107 2016-03-09 00:44:24      14
4        1107 2016-03-09 00:44:26      14
5        1108 2016-03-09 00:54:02       9
6        1108 2016-03-09 00:54:04      10
7        1109 2016-03-09 01:01:37      17
8        1109 2016-03-09 01:01:39       6
9        1110 2016-03-09 01:02:49      10
10       1110 2016-03-09 01:02:49       8

setB:

   session_id            datetime request
        <int>              <dttm>   <dbl>
1        1105 2016-03-09 00:33:45       3
2        1107 2016-03-09 00:44:29       7
3        1108 2016-03-09 00:54:06      10
4        1109 2016-03-09 01:01:40       6
5        1110 2016-03-09 01:02:51       5
6        1111 2016-03-09 01:18:36      14
7        1111 2016-03-09 01:18:38      16
8        1112 2016-03-09 01:21:20       1
9        1112 2016-03-09 01:21:21      19
10       1114 2016-03-09 01:29:58      13

现在我想在这两个集合上做一些交集,但按 sessionid 分组

由于 setA 中的 sessionid 1105 包含请求 (3,7),我想与相同的 sessionid 进行交集,即 setB 中包含请求 (3) 的 1105

calc = intersect(setA$request,setB$request) 

...但按 sessionid 分组。

希望你明白了。

我认为你可以做到:

library(dplyr)
setA %>% 
  inner_join(setB, by = c("session_id", "request"))

这导致数据帧合并,其中 session_id 和请求在两个数据集中相同,丢弃了日期时间。

  session_id request          datetime.x          datetime.y
1       1105       3 2016-03-09 00:33:43 2016-03-09 00:33:45
2       1108      10 2016-03-09 00:54:04 2016-03-09 00:54:06
3       1109       6 2016-03-09 01:01:39 2016-03-09 01:01:40

更新:如果你添加这个,你会得到交叉点的长度:

setA %>% 
  inner_join(setB, by = c("session_id", "request")) %>% 
  group_by(session_id) %>%
  summarise(lengthintersection = n())

  session_id lengthintersection
   <int>              <int>
1       1105                  1
2       1108                  1
3       1109                  1

更新:作为对评论的回应,计算比例的另一个更新:

setA %>%
  group_by(session_id) %>% 
  mutate(numberrequests = n()) %>% 
  inner_join(setB, by = c("session_id", "request")) %>% 
  summarise(proportion = n()/numberrequests)

# A tibble: 3 x 2
      session_id proportion
        <int>      <dbl>
1       1105        0.5
2       1108        0.5
3       1109        0.5

我建议使用很棒的 data.table 包,因为对于许多任务来说它比 dplyr 更快。

我稍微改变了例子,所以有一个长度 > 1 的交集。

library(data.table)
A <- data.table("session_id" = c(1105, 1105, 1107 ,1107 ,1108, 1108, 1120),
                "request" = c(8,3,14,15,9,10, 20))
B <- data.table("session_id" = c(1105, 1107, 1107, 1108, 1109, 1110, 1111),
                "request" = c(3, 15, 14, 9, 6, 5, 9))

首先,我们执行左外连接,从table B:

获取所有请求值
C <- merge(A,B, all.x = T, by = "session_id")

然后我们简单地用方便的"by"操作计算交集的长度并将结果连接回A:

C[, len_inter := length(intersect(request.x, request.y)), by=session_id]
A[C, len_inter := i.len_inter, on="session_id"]

> A
   session_id request len_inter
1:       1105       8         1
2:       1105       3         1
3:       1107      14         2
4:       1107      15         2
5:       1108       9         1
6:       1108      10         1
7:       1120      20         0

PS: 以后请添加一些代码来创建您的示例 data.frames,这样人们就不必手动输入您的 table。