如何从一列逗号分隔值中计算唯一对组合的频率?

How to count frequency of unique pair combinations from a column of comma-separated values?

我有一个数据框,其中有一列(“组合”)以逗号分隔值表示在同一时间段内同时发生的事件类型。我正在寻找一种方法来计算成对组合的频率(顺序无关紧要;即 AB 和 BA 是等效的)。

玩具数据框

+------------------------+
|combo      startts endts|
| A,B       02:20  02:23 |
| A,B,D     02:23  02:25 |
| A,C       02:27  02:28 |
+------------------------+

理想输出:


+---------------------------+
|combo      | count         |
+---------------------------+
|  AB       | 2             |
|  AC       | 1             |
|  AD       | 1             |
|  BC       | 0             |
|  BD       | 1             |
|  CD       | 0             |
+-----------+---------------+

我正在考虑首先生成所有唯一的成对组合,将其放入列中,然后使用正则表达式模式匹配进行条件变异;但是,我不确定如何抽象地引用列名而不是特定的字符串模式(或者如果可能的话)。

感谢您的宝贵时间。

你可以试试这个

输入:

df <- read.table(text = "combo      startts endts
A,B       02:20  02:23
A,B,D     02:23  02:25
A,C       02:27  02:28", header = TRUE)

解决方案:

# user defined functions
pastecollapse <- function(...) paste(..., collapse = "")
sortedcomb2collapse <- function(x) combn(sort(x), m = 2, FUN = pastecollapse)

# get combos
combos <- strsplit(df$combo, split = ",")

# all possible combos
allcombos <- sortedcomb2collapse(unique(unlist(combos)))

# existing combos
mycombos  <- unlist(lapply(combos, sortedcomb2collapse))

# count combos (show missing combos)
as.data.frame(table(combo = factor(mycombos, levels = allcombos)), responseName = "count")

#>   combo count
#> 1    AB     2
#> 2    AC     1
#> 3    AD     1
#> 4    BC     0
#> 5    BD     1
#> 6    CD     0

tidyverse类似:

library(tidyr)
library(dplyr)

df_sep <- df %>% separate_rows(combo)
allcombos <- df_sep %>% pull(combo) %>% unique %>% sortedcomb2collapse

df_sep %>% 
 group_by(startts, endts) %>% 
 summarise(combo = sortedcomb2collapse(combo), .groups = "drop") %>% 
 mutate(combo = factor(combo, levels = allcombos)) %>% 
 count(combo, name = "count", .drop = FALSE)
#> # A tibble: 6 x 2
#>   combo count
#>   <fct> <int>
#> 1 AB        2
#> 2 AC        1
#> 3 AD        1
#> 4 BC        0
#> 5 BD        1
#> 6 CD        0

注意:在您的预期输出中,缺少一种可能的组合 (CD)。是不是搞错了?