计算两个词的共同出现,但顺序在 r 中并不重要

Count co-occurrences of two words but the order is not important in r

我想要什么:我想计算两个词的共现次数。但我不关心它们在字符串中出现的顺序。

我的问题:当两个给定的单词以不同的顺序出现时,我不知道如何处理。

到目前为止: 我使用 unnest_token 函数使用标记参数的“skip_ngrams”选项按单词拆分字符串。然后我过滤了恰好两个词的组合。我使用 separate 创建 word1word2 列。最后算一下出现的次数。

我得到的输出是这样的:

# A tibble: 3 × 3
  word1 word2      n
  <chr> <chr>  <dbl>
1 a     c          3
2 b     a          1
3 c     a          5

但是单词“a”和“c”出现的顺序不同,因此它们被算作不同的元素。我要的是这个:

# A tibble: 2 × 3
  word1 word2      n
  <chr> <chr>  <dbl>
1 a     c          8
2 b     a          1

我的数据:我的数据是这样的,这是整个过程,数据不同但问题相同。在这种情况下,“a b”和“c a”的值应为 n = 2。

library(tidyverse)
library(tidytext)
enframe(c("a b c a d e")) %>% 
  unnest_tokens(skipgram, value, token = "skip_ngrams", n = 5) %>% 
  mutate(n_words = str_count(skipgram, pattern = "\S+")) %>%
  filter(n_words == 2) %>% 
  separate(col = skipgram, into = c("word1", "word2"), sep = "\s+") %>% 
  count(word1, word2) 
#> # A tibble: 9 × 3
#>   word1 word2     n
#>   <chr> <chr> <int>
#> 1 a     b         1
#> 2 a     c         1
#> 3 a     d         1
#> 4 a     e         1
#> 5 b     a         1
#> 6 b     c         1
#> 7 c     a         1
#> 8 c     d         1
#> 9 d     e         1

reprex package (v2.0.1)

于 2022-02-09 创建

在应用 count

之前,我们可以使用 pmin/pmax 按行对列进行排序
library(tidytext)
library(dplyr)
library(stringr)
library(tidyr)
enframe(c("a b c a d e")) %>% 
  unnest_tokens(skipgram, value, token = "skip_ngrams", n = 5) %>% 
  mutate(n_words = str_count(skipgram, pattern = "\S+")) %>%
  filter(n_words == 2) %>% 
  separate(col = skipgram, into = c("word1", "word2"), 
      sep = "\s+") %>%
  transmute(word11 = pmin(word1, word2), word22 = pmax(word1, word2)) %>%
  count(word11, word22)

-输出

# A tibble: 7 × 3
  word11 word22     n
  <chr>  <chr>  <int>
1 a      b          2
2 a      c          2
3 a      d          1
4 a      e          1
5 b      c          1
6 c      d          1
7 d      e          1

非常高效。这是 igraph

的另一个选项
library(tidytext)
library(dplyr)
library(stringr)
library(tidyr)
library(igraph)

enframe(c("a b c a d e")) %>%
  unnest_tokens(skipgram, value, token = "skip_ngrams", n = 5) %>%
  mutate(n_words = str_count(skipgram, pattern = "\S+")) %>%
  filter(n_words == 2) %>%
  separate(col = skipgram, into = c("word1", "word2"), sep = "\s+") %>%
  count(word1, word2) %>%
  graph_from_data_frame(directed = FALSE) %>%
  simplify(edge.attr.comb = "sum") %>%
  get.data.frame()

这给出了

  from to n
1    a  b 2
2    a  c 2
3    a  d 1
4    a  e 1
5    b  c 1
6    c  d 1
7    d  e 1