找到两个不同数据帧内的两个集合的交集,这些数据集由一些var分组

时间:2018-04-25 07:42:29

标签: r dplyr plyr

我有这两个数据帧:

组A

   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分组。

我希望你明白这一点。

2 个答案:

答案 0 :(得分:1)

我认为你可以这样做:

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

这会导致数据框合并,其中session_id和request在两个数据集中都相同,从而丢弃了日期时间。

  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

答案 1 :(得分:0)

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

我稍微改变了一下这个例子,所以有一个长度为&gt的交叉点。 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))

首先,我们执行左外连接以获取表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,这样人们就不必手动输入您的表格。