计算数据框 r 中值的共现次数

count co-occurrences of values in dataframe r

我有一个示例数据框如下,我需要探索 Category 列。

> df
  Id  Category
  1 [1,2,3,4]
  2   [2,3,5]
  3   [1,4,5]
  4   [1,2,5]
  5       [4]
  6   [2,3,5]
  7     [1,5]

实际上,数据框中有数千行类别介于 1 到 25 之间。我想看看这些类别在该列中共同出现了多少次。输出应为矩阵或数据框。

矩阵输出:

     [,1] [,2] [,3] [,4] [,5]
[1,]    0    2    1    2    3
[2,]    2    0    3    1    3
[3,]    1    3    0    1    2
[4,]    2    1    1    0    1
[5,]    3    3    2    1    0

数据帧输出:

     C1 C2     Count
     1  2      2
     1  3      1
     1  4      2
     1  5      3
     2  3      3
     2  4      1
     2  5      3
     3  4      1
     3  5      2
     4  5      1

有人可以在这方面帮助我吗?

在用 strsplit 拆分 'Category' 列后,我们可以将 crossprodtable 一起使用(仅使用 base R 函数)

out <- crossprod(table(subset(stack(setNames(lapply(strsplit(df$Category, 
    "[][]|,\s*"), trimws), df$Id))[2:1], nzchar(values))))
diag(out) <- 0

-输出

> out
      values
values 1 2 3 4 5
     1 0 2 1 2 3
     2 2 0 3 1 3
     3 1 3 0 1 2
     4 2 1 1 0 1
     5 3 3 2 1 0

在上面的代码中,我们通过在 strsplit 中拆分 ,[] 来提取数字部分,将返回的 list 的名称设置为 Id 列,stack named list 到两列 data.frame (stack),使用 table 得到频率计数然后在 table 输出上用 crossprod 换行。然后 diagonals 被替换为 0


如果我们需要长格式 data.frame,则 replace 三角矩阵之一为 0,然后转换为 table 并在用 [ 包装后 subseting =35=]

out2 <-  subset(as.data.frame.table(replace(out, upper.tri(out), 
     0)), Freq != 0)
row.names(out2) <- NULL
colnames(out2) <- c("C1", "C2", "Count")

-输出

> out2
   C1 C2 Count
1   2  1     2
2   3  1     1
3   4  1     2
4   5  1     3
5   3  2     3
6   4  2     1
7   5  2     3
8   4  3     1
9   5  3     2
10  5  4     1

数据

df <- structure(list(Id = 1:7, Category = c("[1,2,3,4]", "[2,3,5]", 
"[1,4,5]", "[1,2,5]", "[4]", "[2,3,5]", "[1,5]")), 
class = "data.frame", row.names = c(NA, 
-7L))

另一个选项:

df %>%
  group_by(Id) %>%
  mutate(Category = list(reticulate::py_eval(Category))) %>%
  unnest(Category) %>%
  table()  %>%
  crossprod() %>%
  as.data.frame.table() %>%
  filter(Category!=Category.1)

   Category Category.1 Freq
1         2          1    2
2         3          1    1
3         4          1    2
4         5          1    3
5         1          2    2
6         3          2    3
7         4          2    1
8         5          2    3
9         1          3    1
10        2          3    3
11        4          3    1
12        5          3    2
13        1          4    2
14        2          4    1
15        3          4    1
16        5          4    1
17        1          5    3
18        2          5    3
19        3          5    2
20        4          5    1