count-lexicon

textmining
nlp
regex
string
Published

November 8, 2023

Aufgabe

Gegeben eines (mehrelementigen) Strings, my_string, und eines Lexicons, my_lexicon, zählen Sie, wie häufig sich ein Wort aus dem Lexikon in einem Element des Strings wiederfindet.

my_string <-
  c("Heute ist ein schöner Tag", "Was geht in dieser Woche?")


my_lexicon <- c("Tag", "Woche", "Jahr")

Hinweise:











Lösung

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.3     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.0
✔ ggplot2   3.4.4     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.0
✔ purrr     1.0.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Paket prada

Eine Möglichkeit ist es, die Funktion count_lexion aus dem Paket prada zu nutzen.

Man kann es so installieren: remotes::install_github("sebastiansauer/prada").

library(prada)
map_int(my_string,  
        ~ count_lexicon(.x, my_lexicon))
[1] 1 1

So können Sie sich den Quellcode einer Funktion, z.B. count_lexicon() anschauen:

count_lexicon
function(txt, lexicon){
  # convert strings to lower letters:
  txt <- tolower(txt)
  lexicon <- tolower(lexicon)

  # build regex query:
  lexicon_regex <- paste0("^", lexicon, "$", collapse = "|")

  # split string into words:
  string_in_words <- unlist(stringr::str_split(txt, pattern = stringr::boundary("word")))

  # search:
  pattern_detected_in_string_count <- sum(stringr::str_detect(string_in_words, pattern = lexicon_regex))

  # return:
  return(pattern_detected_in_string_count)
}
<bytecode: 0x7fb814c232d0>
<environment: namespace:prada>

In dem Paket gibt es noch zwei Varianten für diese Funktion, die auf einem Join aufbauen.

Selbstgestrickt

Hier ist eine zweite Variante ohne besondere Pakete (außer stringr).

Wir definieren eine entsprechende Funktion:

# Funktion, um die Anzahl der Übereinstimmungen eines Lexikons in einem String zu zählen
count_lexicon_matches <- function(string, lexicon) {
  # Verketten Sie die Wörter im Lexikon mit dem |-Operator, um ein reguläres Ausdrucksmuster zu erstellen
  lexicon_pattern <- paste(lexicon, collapse = "|")
  # Verwenden Sie str_count, um die Anzahl der Übereinstimmungen zu zählen
  matches <- str_count(string, lexicon_pattern)
  return(matches)
}

Wir zählen die Übereinstimmungen in jedem Element des Strings:

matches_per_element <- sapply(my_string, count_lexicon_matches, lexicon = my_lexicon)

# Ergebnis ausgeben:
print(matches_per_element)
Heute ist ein schöner Tag Was geht in dieser Woche? 
                        1                         1 

Anstelle von sapply kann man das tidyverse-Pendant, map nutzen:

map_int(my_string,  
        ~ count_lexicon_matches(.x, my_lexicon))
[1] 1 1

Categories:

  • textmining
  • nlp
  • regex
  • string