NoPaste

Entwurf.Rmd

von tegula

SNIPPET_TEXT:
  1. ---
  2. title: "RegExp-Kurs - R (stringr)"
  3. author: "tegula"
  4. date: '2022-07-05'
  5. output: html_document
  6. ---
  7.  
  8. ```{r setup, include=FALSE}
  9. knitr::opts_chunk$set(echo = TRUE)
  10. ```
  11. [Kursübersicht](https://debianforum.de/forum/viewtopic.php?t=183941)
  12.  
  13. # Einleitung
  14. In diesem Thread geht es um die Anwendung von regulären Ausdrücken in R mittels des Packages (der Bibliothek) stringr.
  15.  
  16. > <https://de.wikipedia.org/wiki/R_(Programmiersprache)>: "R ist eine freie Programmiersprache für statistische Berechnungen und Grafiken. Sie wurde 1992 von Statistikern für Anwender mit statistischen Aufgaben neu entwickelt. Die Syntax orientiert sich an der Programmiersprache S, mit der R weitgehend kompatibel ist, und die Semantik an Scheme. Als Standarddistribution wird R mit einem Interpreter als Kommandozeilenumgebung mit reduzierten grafischen Schaltflächen angeboten. So ist R aktuell auf den wichtigsten Plattformen verfügbar; die Umgebung wird von den Entwicklern ausdrücklich ebenfalls als R bezeichnet. R ist Teil des GNU-Projekts".
  17.  
  18. Bei Stringr handelt es sich um einen benutzerfreundliche Oberfläche/Wrapper für die stringi-Bibliothek. Der verwendete Regex-Dialekt wird "ICU" oder "Java-ähnlich" bezeichnet (<https://cloud.r-project.org/web/packages/stringi/index.html>). Die ERE-Ausdrücke, die wir während des Grundlagen-Kurses von Meillo gelernt haben, können (nach Anpassung der Escapezeichen; siehe weiter unten) in der Regel übernommen werden.
  19.  
  20. # Installation
  21.  
  22. R und die für den Kursteil benötigten R-Packages sind in offiziellen Debian-Quellen verfügbar. r-recommendedund r-cran-tidyverse werden benötigt.
  23.  
  24. Optional: Für diesen Kurs-Part reicht prinzipiell ein beliebiger Texteditor. Eine integrierte Entwicklungsumgebung macht die Benutzung von R aber bequemer und einfacher. Eine Übersicht findet sich im Archwiki (<https://wiki.archlinux.org/title/R#Editors_IDEs_and_notebooks_with_R_support>) oder auf Wikipedia <https://en.wikipedia.org/wiki/R_(programming_language)#Interfaces>.
  25.  
  26. # Besondersheiten von R
  27.  
  28. ## Zuweisungsoperator
  29. Im Unterschied zu Python, gibt es in R zwei Möglichkeiten eine Zuweisung auszudrücken. "<-" und "=". Für die Zuweisung eines Wertes an ein Objekt sind beide Schreibweisen möglich. Für die Übergabe eines Schlüsselwortarguments an eine Funktionen oder eine Methode ist hingegen (wie in Python) ausschließlich die Schreibweise "=" erlaubt.
  30. ```{r}
  31. library(magrittr)
  32. data(trees)
  33. # Zuweisung an Objekte: Sowohl "<-" als auch "=" sind erlaubt.
  34.  
  35. volumen_kubikzoll = trees$Volume
  36. volumen_kubikzoll <- trees$Volume
  37. summary(object = volumen_kubikzoll, digit = 4)
  38.  
  39. ```
  40.  
  41. ## Pipe-Operator
  42. Im weiteren Verlauf dieser Einführung wird häufig der Pipe-Operator %>% verwendet. Der Pipe-Operator ermöglicht es zwei Funktionen miteinander zu verknüpfen. Das heißt die zweite Funktion verwendet den Rückgabewert der ersten Funktion als (ootb: erstes positionales) Argument. Der Pipe-Operator stellt damit eine IMHO flexiblere und übersichtlichere Alternative zu Klammern da. Um den Pipe-Operator verwenden zu können, ist es allerdings erforderlich, zuvor entweder das Package magrittr oder Meta-Package tidyverse zu laden.
  43. ```{r}
  44. library(magrittr)
  45. data(mtcars) # Beispieldatensatz (ist in R enthalten) laden
  46.  
  47. # Folgendes wird gemacht: Die Antriebsleistung der Autos wird von Pferdestärken (Pferdestärken) in Kilowatt (kW) umgerechnet. Anschließen werden das (als Zahl vorliegende) Ergebnis in eine Zeichenkette umwandelt. Zum Schluss wird die Angabe der Einheit ("kW") zu dieser  Zeichenkette hinzufügt.
  48.  
  49. ## Variante 1: Mit Klammern (ohne Pipe-Operator) --> IMHO eher unübersichtlich
  50. paste((as.character(multiply_by(mtcars$hp, 0.746))), "kW", sep = " ")
  51. ## Variante 2: Mit Pipe-Operator (in einer Zeile) --> IMHO schon übersichtlicher
  52. mtcars$hp %>% multiply_by(0.746) %>% as.character %>% paste("kW", sep = " ")
  53. ## Variante 3: Mit Pipe-Operator (in mehren Zeilen --> IMHO noch mal  übersichtlicher
  54. mtcars$hp %>%
  55.   multiply_by(0.746) %>%
  56.   as.character %>%
  57.   paste("kW", sep = " ")
  58. ```
  59. Weitergehende Infos (für Kurs-Part nicht nötig): <https://magrittr.tidyverse.org>
  60.  
  61. ## Escaping
  62. Als Escapezeichen dient der Backslash. Eine Besonderheit innerhalb R ist jedoch, dass grundsätzlich doppelt escapet werden muss, um aus einen Standardzeichen ein Metazeichen zu machen. _De facto_ dient also ein doppelter Backslash als Escape-Zeichen.
  63.  
  64. ```{r}
  65. library(tidyverse)
  66. # TODO: Es soll nur die Schreibweise mit zwei getrennten Wörter ("hallo debianforum") gefunden werden.
  67. ## richtig:
  68. "hallo_debianforum hallo debianforum" %>%
  69.   str_extract_all(pattern = "hallo\\b.debianforum")
  70. ## falsch:
  71. "hallo_debianforum hallo debianforum" %>%
  72.   str_extract_all(pattern = "hallo\b.debianforum")
  73. ```
  74.  
  75. Weitergehende Infos: <https://raw.githubusercontent.com/rstudio/cheatsheets/main/strings.pdf> (Seite 2, linke Spalte "Need to Know").
  76.  
  77. # Übersicht über die in stringr möglichen regulären Ausdrucke
  78.  
  79. Ein tabellarische Übersicht der innerhalb von stringr zur Verfügung stehenden Operationen und Zeichenklassen bietet die zweite Seite des Cheat-Sheets "strings" von Rstudio: <https://github.com/rstudio/cheatsheets/blob/main/strings.pdf>. Eine Übersicht als Fließtext liefert die die Vignette "regular expressions": <https://cloud.r-project.org/web/packages/stringr/vignettes/regular-expressions.html>.
  80.  
  81. # Funktion im stringr-Package
  82.  
  83. Die Überblick über die in stringr enthaltenen regex-Funktionen ist zum Beispiel in der Vignette "Introduction to stringr" zu finden: <https://stringr.tidyverse.org/articles/stringr.html#pattern-matching> zu finden. Eine ausführliche Beschreibung findet sich in der Befehlsreferenz des stringr-Packages: <https://cloud.r-project.org/web/packages/stringr/stringr.pdf>.
  84.  
  85. # Vorbereitung
  86.  
  87. ## Arbeitsverzeichnis festlegen, Script-Datei erstellen und Schwäbische Kunde downloaden:
  88. Erstellt ein Verzeichnis (z. B. ~/regex_R) für diesen Kurs-Part und speichert dort eine leere Textdatei mit der Dateinamensendung ".R" (z. B. skript_regex.R) sowie die Schwäbische_Kunde (<https://nopaste.debianforum.de/41651>). Öffnet das Script und fügt folgenden Befehl ein, um das Arbeitsverzeichnis festzulegen.
  89. ```{r eval=FALSE}
  90. #!/usr/bin/env Rscript #optional
  91. setwd(~/regex_R) # Arbeitsverzeichnis festlegen (Pfad ggf. anpassen)
  92. getwd()          # Arbeitsverzeichnis anzeigen
  93. print("Das ist ein Test") # Zeichenkette "Das ist ein Test" ausgeben
  94. ```
  95.  
  96. ## Skript ausführen (Ohne Entwicklungsumgebung):
  97. (Wenn ihr eine Entwicklungsumgebung zum Ausführen des Befehle bzw. eures Skripts nutzt, könnt ihr diesen Abschnitt überspringen.)  
  98. Öffnet ein Terminal, wechselt in eurer Arbeitsverzeichnis und übergebt das Script an das Programm Rscript. Daraufhin wird das Skript ausgeführt.
  99. ```{bash eval=FALSE}
  100. cd ~/regex_R # Pfad zum Arbeitsverzeichnis ggf. anpassen
  101. Rscript skript_regex.R # Pfad ggf. anpassen
  102.  
  103. ```
  104.  
  105. ## Schwäbische Kunde importieren und für spätere Verwendung abspeichern.
  106. Zum importieren der Schwäbischen Kunde benutzen wir die Funktion read_lines aus dem Package readr. Das Ergebnis des Imports speichern wir unter dem Dateinamen "schwaebische_kunde.RData" ab, um es später wiederverwenden zu können.
  107.  
  108. ```{r}
  109. # Importieren
  110. schwaebische_kunde <- readr::read_lines("schwaebische-kunde.txt") %>%
  111.   dplyr::as_tibble() %>%
  112.   dplyr::rename(text = value) %>%
  113.   tibble::rowid_to_column("zeile")
  114. # abspeichern
  115. save(schwaebische_kunde, file = "schwaebische_kunde.RData")
  116. ```
  117.  
  118. # Funktion im stringr-Package
  119. Ein Überblick über die in stringr enthaltenen regex-Funktionen ist zum Beispiel in der Vignette "Introduction to stringr" zu finden: <https://stringr.tidyverse.org/articles/stringr.html#pattern-matching> zu finden. Eine ausführliche Beschreibung findet sich in der Befehlreferenz des stringr-Packages: <https://cloud.r-project.org/web/packages/stringr/stringr.pdf>.
  120.  
  121. ## Feststellen, ob ein Match vorliegt: str_detect
  122. ```{r}
  123. # Tidyverse laden
  124. library(tidyverse)
  125. # Schwäbische Kunde laden
  126. load("schwaebische_kunde.RData")
  127. # Regex-Funktion ausführen:
  128. ## Zeile enthält einen Punkt
  129. schwaebische_kunde$is_match <- schwaebische_kunde$text %>%
  130.   str_detect(pattern = "[:punct:]")
  131. # Ergebnis ausgeben
  132. schwaebische_kunde %>%
  133.   print(n = Inf)
  134. ```
  135.  
  136. ## Feststellen eines Matches am Beginn bzw. Ende einer Zeichenfolge: str_starts und str_ends
  137. Soll nur der Beginn bzw. Ende einer Zeichenfolge betrachtet werden, so  bietet sich die Nutzung der Funktionen str_starts bzw. str_ends an. Die Angabe der Zeilenanker ^ und $ kann bei der Verwendung dieser Funktionen entfallen.
  138. ```{r}
  139. input_string <- "debianforum.de"
  140.  
  141. # Match am Anfang einer Zeichenfolge feststellen
  142. input_string %>% str_starts(pattern = "[dD]") # entspricht ...
  143. input_string %>% str_detect(pattern = "^[dD]")
  144.  
  145. # Match am Ende einer Zeichenfolge feststellen
  146. input_string %>% str_ends(pattern = "de")
  147. input_string %>% str_detect(pattern = "de")
  148. ```
  149.  
  150. ## Anzahl der Matches bestimmen: str_count
  151. ```{r}
  152. # Tidyverse laden
  153. library(tidyverse)
  154. # Schwäbische Kunde laden
  155. load("schwaebische_kunde.RData")
  156. # Regex-Funktion ausführen
  157. ## Wörter je Zeichenfolge (entspricht hier: Wörter je Strophe)
  158. schwaebische_kunde$n_matches <- schwaebische_kunde$text %>%
  159.   str_count(pattern = "\\b[:alpha:]")
  160. # Ergebnis anzeigen
  161. schwaebische_kunde %>%
  162.   print(n = Inf)
  163. ```
  164.  
  165. ## Position des _ersten_ Matches bestimmen: str_locate
  166. ```{r}
  167. # Tidyverse laden
  168. library(tidyverse)
  169. # Schwäbische Kunde laden
  170. load("schwaebische_kunde.RData")
  171. # Regex-Funktion ausführen
  172. ## erstes auftreten des Buchstaben A bzw. a
  173. schwaebische_kunde$position <-  schwaebische_kunde$text %>%
  174.   str_locate(pattern = "[aA]")
  175. # Ergebnis anzeigen
  176. schwaebische_kunde %>%
  177.   print (n = Inf)
  178. ```
  179.  
  180. ## Position _aller_ matches bestimmen: str_locate_all
  181. ```{r}
  182. # Tidyverse laden
  183. library(tidyverse)
  184. # Schwäbische Kunde laden
  185. load("schwaebische_kunde.RData")
  186. # Regex-Funktion ausführen
  187. ## jedes auftreten von A bzw. a
  188. str_locate_all(string = schwaebische_kunde$text,
  189.                pattern = "[Aa]")
  190. ```
  191.  
  192. ## _erstes_ Match extrahieren:
  193. ```{r}
  194. # Tidyverse laden
  195. library(tidyverse)
  196. # Schwäbische Kunde laden
  197. load("schwaebische_kunde.RData")
  198. # Regex-Funktion ausführen
  199. ## Der auf "schwäb" oder "schwab" folgende
  200. schwaebische_kunde$first_match <- schwaebische_kunde$text %>%
  201.   str_match(pattern = "[aA]")
  202. # Ergebnis anzeigen
  203. schwaebische_kunde %>%
  204.   print (n = Inf)
  205. ```
  206.  
  207. ## _alle_ Matches extrahieren: str_extract_all
  208. ```{r}
  209. # Tidyverse laden
  210. library(tidyverse)
  211. # Schwäbische Kunde laden
  212. load("schwaebische_kunde.RData")
  213. # Regex-Funktion ausführen
  214. ## jedes auftreten von A bzw. a
  215. schwaebische_kunde$text %>%
  216.   str_extract_all(pattern = "[aA]")
  217. # Ergebnis anzeigen
  218. schwaebische_kunde %>%
  219.   print (n = Inf)
  220. ```
  221.  
  222. ## Gruppen extrahieren (nur erstes match): str_match
  223. ```{r}
  224. # Tidyverse laden
  225. library(tidyverse)
  226. # Schwäbische Kunde laden
  227. load("schwaebische_kunde.RData")
  228. # Regex-Funktion ausführen
  229. ## Extrahiere das Wort vor dem ersten Komma oder Punkt
  230. schwaebische_kunde$first_match_group <- schwaebische_kunde$text %>%
  231.   str_match(pattern = "([:alnum:]*)[:blank:]*[.,].*")
  232. # Ergebnis anzeigen
  233. schwaebische_kunde %>%
  234.   print (n = Inf)
  235. ```
  236.  
  237. ## Gruppen extrahieren (alle matches): str_match_all
  238. ```{r}
  239. # Tidyverse laden
  240. library(tidyverse)
  241. # Schwäbische Kunde laden
  242. load("schwaebische_kunde.RData")
  243. # Regex-Funktion ausführen
  244. ## Extrahiere alle Lleinbuchstaben, die auf einen Großbuchstaben folgen
  245. schwaebische_kunde$text %>%
  246.   str_match_all("[:upper:]([:lower:])")
  247. ```
  248.  
  249. ## (Komplette) Zeichenkette zurückgeben, wenn mindestens ein Match enthalten ist: str_subset
  250. ```{r}
  251. # Tidyverse laden
  252. library(tidyverse)
  253. # Schwäbische Kunde laden
  254. load("schwaebische_kunde.RData")
  255. # Regex-Funktion ausführen:
  256. ## Zeichenfolgen (Zeilen), die ein Komma enthalten
  257. schwaebische_kunde$text %>% str_subset(pattern = ",")
  258. ```
  259.  
  260. ## Ersetzen (nur erstes Match ersetzen): str_replace
  261. ```{r}
  262. # Tidyverse laden
  263. library(tidyverse)
  264. # Schwäbische Kunde laden
  265. load("schwaebische_kunde.RData")
  266. # Regex-Funktion ausführen:
  267. ## Ersetze das erste Auftreten von "ae" durch "ä"
  268. schwaebische_kunde$text <- schwaebische_kunde$text %>%
  269.   str_replace(pattern = "ae",
  270.               replacement = "ä")
  271. # Ergebnis ausgeben
  272. schwaebische_kunde %>%
  273.   print(n = Inf)
  274. ```
  275.  
  276. ## Ersetzten (alle Matches ersetzen): str_replace_all
  277. ```{r}
  278. # Tidyverse laden
  279. library(tidyverse)
  280. # Schwäbische Kunde laden
  281. load("schwaebische_kunde.RData")
  282. # Regex-Funktion ausführen:
  283. ## Ersetze alle Leerzeichen durch Unterstriche
  284. schwaebische_kunde$text <- schwaebische_kunde$text %>%
  285.   str_replace_all(pattern = "[:space:]",
  286.                   replacement = "_")
  287. # Ergebnis anzeigen
  288. schwaebische_kunde %>%
  289.   print(n = Inf)
  290. ```
  291.  
  292. # Aufgaben
  293. 1. Bestimme, wie viele Buchstaben, die URL des dfde-Unterforums "Softwareentwicklung und -paketierung, Scripting" (<https://debianforum.de/forum/viewforum.php?f=34>) enthält. Zähle einmal mit und einmal ohne die Angabe des Protokolls ("https").
  294. 2. Bestimme wie viele Verse (Zeilen) der Schwäbischen Kunde mit einem Vokal (Selbstlaut) beginnen.
  295. 3. Mehrere Einwohner von Neu New York wurden nach ihrer Lieblingsfarbe gefragt. Das Ergebnis findest du im NoPaste: <https://nopaste.debianforum.de/41775>. Ordne ihren Antworten mit Hilfe regulärer Ausdrücke den folgenden Kategorien zu "Rot", "Blau", "Grün", "Andere Farbe" und NA (fehlender Wert).
  296. 4.) Extrahiere aus der Schwäbischen Kunde alle Großbuchstaben. Formatiere die Ausgabe so, dass gentrennt nach Verse (Zeilen) folgende Informationen möglich übersichtlich angezeigt werden: 1.) Zeilenummer des Verses. 2.) Gesamter Text des Verses. 3.) Alle Großbuchstaben, die in diesem Verses enthalten sind. Du bist frei in der Wahl des Ausgabemediums (z. B. R-Konsole, Standardausgabe, Spreadsheet-Datei oder ähnliches).
  297. 5.) Denke Dir selbst eine Aufgabe für die anderen Teilnehmer dieses Kursteils aus.
  298. 6.) Löse die Aufgaben der anderen Teilnehmer.
  299.  
  300. Bitte postet Eure Lösungen zu den Aufgaben 1-5 _frühestens_ ab Mittwoch (13. Juli). Bitte denkt als Aufgabenersteller bei Aufgabe 6 daran, anzugeben, ab wann Lösungen zu Eurer Aufgabe frühestens gepostet werden sollen :).

Quellcode

Hier kannst du den Code kopieren und ihn in deinen bevorzugten Editor einfügen. PASTEBIN_DOWNLOAD_SNIPPET_EXPLAIN