servr::daemon_stop(1)
xaringan::inf_mr()

Arbeit mit character-Vektoren: paste()

given_name <- c("Angela", "Olaf", "Annalena")
name <- c("Merkel", "Scholz", "Baerbock")
paste(given_name[1], name[1])
paste(given_name, name) # Vektorisierung - der effiziente Weg!
paste(name, given_name, sep = ", ")
paste(name, collapse = " - ")

Formattierung von Strings

# Wert von character-Vektoren wird bei %s eingefügt
sprintf("%s, %s", name, given_name) 
sprintf("%d-%02d-%02d", 2021, 5,4) # Einfügen von numerischen Werten
is_woman <- c(TRUE, FALSE, TRUE)
sprintf("Kandidat%s %s", ifelse(is_woman, "in", ""), name)

Splitten von Strings

dates_din <- c("2020-06-02", "2020-05-13", "2021-09-27")
s <- strsplit(dates_din, split = "-") # Liste als Rückgabewert!
s

Szenario: Umwandlung eines DIN -Datums in deutsche Datumsangabe

sprintf("%s.%s.%s", sapply(s, `[`, 3), sapply(s, `[`, 2), sapply(s, `[`, 1))

False friends I: Datumsangaben

Die Versuchung ist oft groß, Datumsangaben als character-Vektoren zu verarbeiten. Das kann aber umständlich und ineffizient sein: Die Nutzung der Klasse Date ist oft besser!

d <- as.Date(dates_din)
is(d)
d
format(d, "%d.%m.%Y") # Effizient und 

r fontawesome::fa("far fa-lightbulb") Insbesondere bei der Arbeit mit Zeitreihen-Daten spielen Datumsobjekte ihre Stärken aus (vgl. Pakete zoo und xts)


False friends II: Pfadangaben

Die Versuchung liegt oft nahe, Pfadangaben als String-Maninpulation zu bearbeiten. Es gibt jedoch eine gesonderte Funktionalität. Hinweis: Die Konsistenz des fs-package hat große Vorteile ...

tp <- tempdir()
tp
f <- file.path(tp, "newfile.txt")
basename(f)
dirname(f)
tools::file_ext(f)

base R-Vokabelheft

Weitere nützliche Basis-Operationen mit Strings:

tolower("BTW2021")
toupper("btw2021")
substr("btw2021", 4, 7)
nchar("btw2021")

Das tückische Thema der Encodings

localeToCharset() # meist bei Windows: "ISO-8859-1", bei macOS: "UTF-8"
verbs <- c("müssen", "dürfen", "wollen")
Encoding(verbs)
iconv(verbs, from = "UTF-8", to = "ISO-8859-1")

Schwierigkeiten mit Encodings erkennen Sie oft daran, dass Zeichen "zerschossen" angezeigt werden. Oft gibt es aber auch unsichtbare Probleme, die nur durch merkwürdiges Verhalten des Codes auffallen (Bsp. ein regulärer Ausdrück trifft nicht das, was er treffen sollte). Es hilft nur regelmäßiges Prüfen, ob das Encoding von character-Vektoren Ihren Annahmen entspricht ...


Suche nach Muster: grep()

Oft will man in character-Vektoren identifizieren, welche Elemente einem Muster entsprechen ...

candidates_names <- paste(name, given_name, sep = ", ")
grep("Scholz", candidates_names) # default behavior: Rückgabe Position
grep("Scholz", candidates_names, value = TRUE)

Szenario: Auffinden von Variablen zur Stimmabgabe im GLES-Datensatz

library(gles)
pos <- grep("Stimmabgabe", sapply(bt2017vw, attr, "label"))
colnames(bt2017vw)[pos]

Das wahre Potential von grep() liegt jedoch in der Möglichkeit der Nutzung regulärer Ausdrücke!


Reguläre Ausdrücke: Zeichenklassen

| Ausdruck | Beschreibung | |:-------:| --------------| | . |Ein Punkt (".") steht für ein beliebiges Zeichen | | \d | "digit" (Ziffer), d.h. 0 bis 9 | | \s | "whitespace" - Leerzeichen | | \w | Buchstaben (keine Ziffern oder Leerzeichen) | | $ | Ende eines Strings | | ^ | Anfang eines Strings |


Quantoren

| Ausdruck | Beschreibung | |:-------:| --------------| |?|Der voranstehende Ausdruck kommt kein- oder einmal vor.| |+|Der voranstehende Ausdruck tritt einmal oder mehrfach auf. | |*|Der voranstehende Ausdruck tritt keinmal oder beliebig oft auf.| |{n}|Der voranstehende Ausdruck tritt exakt n-fach auf.| |{min,}| Der voranstehende Ausdruck tritt mindestens min-fach auf.| |{min,max}|Der voranstehende Ausdruck tritt mindestens min-fach und maximal max-fach auf.| |{0,max}| Der voranstehende Ausdruck darf maximal max-fach vorkommen.|


Ersetzungen mit gsub()

gsub(",\\s+.*$", "", candidates_names)
gsub("-\\d{2}-\\d{2}$", "", "2021-09-27")

Mit Klammern (capturing parentheses) gruppieren und ordnen ...

gsub("^(\\d{4})-(\\d{2})-(\\d{2})$", "\\3.\\2.\\1", "2021-09-27")

pdf-Dokumente: Text extrahieren

gruene_btw2021 <- "https://cms.gruene.de/uploads/documents/2021_Wahlprogrammentwurf.pdf"
gruene_btw2021_local <- tempfile()
download.file(url = gruene_btw2021, destfile = gruene_btw2021_local)
library(pdftools)
info <- pdftools::pdf_info(gruene_btw2021_local)
txt <- pdftools::pdf_text(gruene_btw2021_local)

Säuberung des Textes

txt <- gsub("-\\n", "", txt) # Silbentrennungen entfernen
txt <- gsub("\\n", " ", txt) # Zeilenumbrüche entfernen
txt <- gsub("\\s+", " ", txt) # große Lücken entfernen

Tokenisierung des Textes

word_list <- strsplit(x = txt, split = "\\s") # Einfachste "whitespace"-Tokenisierung
words <- unlist(word_list)
length(words)
words_cleaned <- gsub("[,:\\.!?]", "", words) # Interpunktion entfernen
words_cleaned <- tolower(words_cleaned) # Kleinschreibung 
words_cleaned <- words_cleaned[!words_cleaned %in% tm::stopwords("de")] # Stopworte
length(words_cleaned)

Zählen

words_count <- table(words_cleaned)
words_count_sorted <- words_count[order(words_count, decreasing = TRUE)]
head(words_count_sorted, 25)

Eine erste Wortwolke: Code

library(wordcloud)

wc <- wordcloud(
  words = names(words_count_sorted)[1:50],
  freq = unname(words_count_sorted)[1:50],
  random.color = TRUE,
  colors = RColorBrewer::brewer.pal(9, "Set1")
)

r fontawesome::fa("far fa-lightbulb") Wortwolken mögen nett anzusehen sein, sind aber im wissenschaftlichen Kontext bestenfalls gut, um Semantik impressionistisch zu vermitteln


Eine erste Wortwolke:

library(wordcloud)

wc <- wordcloud(
  words = names(words_count_sorted)[1:50],
  freq = unname(words_count_sorted)[1:50],
  random.color = TRUE,
  colors = RColorBrewer::brewer.pal(9, "Set1")
)

Natural Language Processing (NLP)


Übungsaufgaben

Laden Sie und säubern Sie das Wahlprogramm ...

... der SPD (https://www.spd.de/zukunftsprogramm/)

... der Union / CDU/CSU

... der FDP

... der Partei Die LINKE

... der AfD

Und erstellen Sie eine Wortwolke mit den häufigsten Worten.



ablaette/learningR documentation built on July 1, 2023, 1:11 a.m.