使用dplyr为给定组创建值的唯一组合的向量

时间:2018-07-22 16:42:34

标签: r dplyr

我有一个数据集,其中每行包含一个事件标识符,而各列包含有关受邀者和组织者的信息。多行将具有相同的事件标识符。我想汇总事件标识符,生成唯一的受邀者和组织者的列表。

假设我有以下数据集:

test <- data.frame(id = stringi::stri_rand_strings(100, 1, '[A-Z]'), invitee_id = floor(runif(100, min=0, max=500)), organizer_id = floor(runif(100, min=0, max=500)))

我想对'id'变量进行分组,并创建一个新列,该列是一个用逗号分隔的矢量,其中包含vitate_id和organizer_id的所有唯一值。第一行的最终结果可能类似于:

> final_df
    id invitee_id organizer_id unique_vals
1    L        481          396 (481, 396, 300, 100, 200)

我们在final_df上崩溃的位置。

我尝试过类似的事情:

final_df <- test %>% 
  group_by(id) %>% 
  distinct(invitee_id, .keep_all=TRUE) 

最终目标是一个邻接矩阵,其中行和列是与会者的ID,其值表示共享事件的数量。

更清楚的例子:

假设我有这个测试数据

> test
   id invitee_id organizer_id
1   A        478          444
2   A        226          346
3   A        338          320
4   A        286          497
5   B        478          327
6   B        226          354
7   B        123          272
8   C        226          297
9   C        338          144
10  C        477           73

我正在尝试按id分组并在受邀者和组织者之间进行汇总,如下所示:

> final_df
   id invitee_id_merged   organizer_id_merged  grouped_values
1   A  c(478, 226, 338)   c(444, 346, 320)     c(478, 226, 338, 444, 346, 320)

最终目标是一个邻接矩阵,其中被邀请者和组织者ID的唯一列表代表行和列。给定的行,列的值应表示这两个人在事件中相遇的次数。所以第一行看起来像这样:

> final_matrix
invitee_or_organizer

    478 226 338 286 123 477 ...
478 2
226 1
338 1
286 1
123 0
477 0 
 ...

2 个答案:

答案 0 :(得分:1)

按'id'分组后,我们可以summarise连接两列的所有unique元素

test %>% 
  group_by(id) %>% 
  summarise_all(funs(toString(unique(.))))

另一种选择是将unique元素存储为list

library(tidyverse)
test %>% 
  group_by(id) %>% 
  summarise_all(funs(merged = list(unique(.)))) %>%
  mutate(grouped_values = map2(invitee_id_merged, organizer_id_merged, c))

此外,根据描述,最终结果是否为邻接数据集中的频率计数

test %>% 
   count(invitee_id, organizer_id) %>%
   spread(organizer_id, n, fill = 0)

更新

基于OP帖子中的修改

crossprod(table(rep(test$id, 2), unlist(test[-1])))

答案 1 :(得分:1)

如果您想要一个数据帧,其中列和行均由invitee_idorganizer_id的联合给出,并且值将是它们都参与的事件的不同计数,这应该是实现这一目标的一种方式:

library(reshape2)
library(dplyr)

test %>%
  melt('id', value.name = 'person_id') %>%
  dcast(person_id~person_id, fun.aggregate = n_distinct, value.var = 'id')