在按某个变量分组的两个不同数据帧中查找两组的交集
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。
我有这两个数据框:
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。