In diesem Beitrag zeigen wir einige Möglichkeiten, wie man in R mit dem Paket stringR Strings und Texte bearbeitet und Informationen daraus extrahiert.
Dafür benötigen wir zunächst einen kleinen Text-Datensatz. Wir nutzen das Paket textdata,
um einen Test-Text zu haben.
# install.packages("textdata")
library(textdata)
catalogue
Interessant ist der Datensatz dataset_dbpedia, der Auszüge aus der gleichnamigen Webseite enthält. Wir nutzen nicht den ganzen Datensatz, sondern nur die ersten 10 Zeilen.
DBPedia <- dataset_dbpedia()
AuszugDBPedia <- DBPedia[1:10,]
AuszugDBPedia

Stringr nutzen
Suche von Mustern in Texten
In der Arbeit mit Strings werden häufig RegEx-Muster (reguläre Ausdrücke) genutzt. Diese Zeichenfolhen sind ewas gewöhungsbedürftig, aber wir versuchen hier einige einfache RegEx-Muster vorzustellen. Für eine Übersicht stehen im Internet verschiedene CheatSheets zur Verfügung. Im Zusammenhang mit stringr können wir das stingr Cheatsheet von RStudio empfehlen.
Wir haben 10 verschiedene Texte. Wir fragen uns, zum Beispiel, welche Unternehmen sich mit Stiften beschäftigen. Anders ausgedrückt: Wir interessieren uns, in welchem Text das Wort "pen" für Stift steht. Der reguläre Ausdruck ist von uns als " pen(s)? " gewählt. Wir suchen als nach allen Stellen, an denen ein Leerzeichen gefolgt von den Buchstaben pen oder pens gefolgt wiederum von einem Leerzeichen vorkommen. Der Bereich (s)? bedeutet dass ein s null oder einmal vorkommt.
Zur Suche können wir die Befehle `str_detect`, `str_which`, `str_count` und `str_locate` nutzen. Auch die Funktion `str_view` kann sehr hilfreich sein, denn sie zeigt die gefundenen Textstellen innerhalb des Textes an.
library(stringr)
# RegEx " pen(s)? " kann pen und pens zurückgeben
str_which(AuszugDBPedia$description, pattern = " pen(s)? ")

Aber ist das auch das was wir suchen? Finden wir es mit str_view_all() heraus:
str_view_all(AuszugDBPedia$description, pattern = " pen(s)? ")

Wunderbar, wir erkennen, dass innerhalb des Text-Ausschnitts nur bei dem Eintrag für Stabilo Stifte vorkommen.
Texte teilen
Im Bereich der Text-Analyse ist es hilfreich Strings in Substrings zerlegen zu können. Benötigt werden meistens einzelne Wörter, Buchstaben, Buchstabengruppen oder Sätze. Wir wollen hier den Auszug aus DBPedia in einzelne Sätze zerteilen.
Sätze können durch die Zeichen . ! und ? voneinander getrennt sein. Als regulärer Ausdruck dient nun "(\\.|\\!|\\?) +". Das heißt, dass wir nach einem der Zeichen . oder ! oder ? suchen. Das Zeichen wird von einem oder keinem Leerzeichen gefolgt.
Schauen wir, ob unsere Idee funktioniert mittels str_view:
str_view_all(AuszugDBPedia$description, pattern = "(\\.|\\!|\\?) +")

Perfekt, dass scheint zu funktionieren. Nun trennen wir die Sätze.
str_split(string = AuszugDBPedia$description, pattern = "(\\.|\\!|\\?) +")

Nun haben wir eine Liste erhalten, die die einzelnen Sätze enthält. Aber wir haben die
Satztrennzeichen entfernt. Dazu gibt es jedoch einen Work-Around: `Look Arounds`innerhalb der RegEx-Muster
str_split(string = AuszugDBPedia$description, pattern = "(?<=(\\.|\\!|\\?)) +")

Wunderbar, nun haben wir die Sätze getrennt und die Satztrennzeichen erhalten.
Leerzeichen und anderen Whitespace entfernen
Arbeitet man mit Texten aus verschiednen Dateiformaten und Quellen, so hat man teilweise viele Leerzeichen
im Text. stringr hat dafür das passende Werkzeug: `str_trim` und `str_squish`
Zunächst erzeugen wir uns einen Beispieltext:
# Helge Schneider Katzeklo :)
LovelyWhitespace <- " Katzenklo, Katzenklo-ja das macht die Katze froh,
Katzenklo, Katzenklo macht die Katze froh.
Willst du eine saubere Katze haben,
Musst du im Geschäft nach Katzenklo fragen.
Katzenklo, Katzenklo-ja das macht die Katze froh,
Katzenklo, Katzenklo macht die Katze froh.
Katzenklo, Katzenklo-ja das macht die Katze froh,
Katzenklo, Katzenklo macht die Katze froh.
Gehst du ins Geschäft hinein,
Kauf was Schönes für die Katze ein. "
Whitespace ist ziemlich störend. Man kann es auch durch einen str_replace_all() aufruf entfernen. Etwa alle Leezeichen mit dem regulären Ausdruck `[[:space:]]`.
str_replace_all(LovelyWhitespace, pattern = "[[:blank:]]+", replacement = " ")

Mit `str_trim` und `str_squish`geht das noch einfacher:
# Whitespace am Anfang und Ende entfernen
str_trim(LovelyWhitespace)

Nun testen wir noch str_squish:
# Alle überflüssigen Whitespace-Zeichen und Zeilenumbrüche entfernen
str_squish(LovelyWhitespace)

Zum Schluss noch etwas Spaß beim Dechiffrieren
James Veitch ist ein Britischer Stand-Up-Comedian, der unter anderem sehr viele
Spam-Mails beantwortet hat. In einer Spam-Korrenspondenz fordert er einen Geheim-Code im Text zu verwenden.
Der Spam-Sender verwendet diesen. Wir werden den Text zurückübersetzen:
JamesVeitchLostInTranslation <- "The business is on. I am trying to raise the balance for the gummy bear so he can submit all the needed fizzy cola bottle jelly beans to the cream egg for the peanut M&Ms process to start. Send 1500 Pounds via a giant gummy lizard."
JamesVeitchLostInTranslation
# Wir schreiben sicherheitshalber alles groß, damit auch keine falschen Muster erkannt werden:
JamesVeitchLostInTranslation <- str_to_upper(JamesVeitchLostInTranslation)
JamesVeitchLostInTranslation
# 1. Gummy bear = lawyer
JamesVeitchTranslated <- str_replace_all(JamesVeitchLostInTranslation, pattern = "GUMMY BEAR", replacement = "LAWYER")
JamesVeitchTranslated
str_view_all(string = JamesVeitchTranslated, pattern = "LAWYER")

Nun automatisieren wir das Entschlüsseln des gesamten Textes
## Automatisieren
NamenDict <- str_to_upper(c("lawyer", "bank", "legal", "claim", "documents", "Western Union"))
Dict <- str_to_upper(c("gummy bear", "cream egg", "fizzy cola bottle", "peanut M&Ms","jelly beans", "a giant gummy lizard"))
names(Dict) <- NamenDict
JamesVeitchTranslated <- JamesVeitchLostInTranslation
for(i in 1:length(Dict)){
# print(Dict[i])
# print(names(Dict[i]))
JamesVeitchTranslated <- str_replace_all(JamesVeitchTranslated, pattern = as.character(Dict[i]), replacement = as.character(names(Dict[i])))
}
JamesVeitchLostInTranslation
JamesVeitchTranslated
# Text wieder mit korrekter Groß-/Kleinschreibung darstellen
str_to_sentence(JamesVeitchTranslated)

Fazit
Mit Texten zu arbeiten heißt auch mit regulären Ausdrücken umzugehen, um Textelemente zu extrahieren oder zu ersetzen. Das Paket stringr kann genau bei diesen Aufgaben helfen. Besonders interessant ist die Funktion `str_view_all`, denn sie visualisiert die gefundenen Elemente im Text. Auch `str_squish` ist hilfreich, denn es entfernt überflüssiges Whitespace aus dem Datensatz. Viel Spaß beim Ausprobieren.
Comments