【问题标题】:Finding inteserction of two sets within two different dataframes grouping by some var在按某个var分组的两个不同数据帧中查找两组的交集
【发布时间】:2018-04-25 07:42:29
【问题描述】:

我有这两个数据框:

设置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 进行交集,即 1105 在 setB 中包含请求 (3)

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

...但按 sessionid 分组。

希望你能明白。

【问题讨论】:

  • 你能指定输出吗?您要求intersection,但您给出的示例中的datetimes 不同。你想丢弃datetime 吗?还是您要求合并?
  • 放弃日期时间,我想根据请求变量的交叉点长度

标签: r dplyr plyr


【解决方案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

【讨论】:

  • 好的,除以 setA 对应 sessionIds 长度的长度(即 1105 中的 2)的长度...我将标记为答案谢谢。上帝保佑你 Len
  • 我不确定你的意思。您想知道 setA 中的请求在 set B 中所占的比例,按 sessionID 分组吗?那么对于 1105,它应该评估为 0.5?
  • 是的,你明白了。
【解决方案2】:

我建议使用很棒的 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))

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-26
    • 1970-01-01
    • 2012-05-12
    • 2015-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-25
    相关资源
    最近更新 更多