NoPaste

Entwurf_V2.Rmd

von tegula
SNIPPET_DESC:
TODO: 1.) Umwandlung rmd -> bbcode. 2.) Rechtschr./Grammatik
SNIPPET_CREATION_TIME:
07.07.2022 13:52:44
SNIPPET_PRUNE_TIME:
Unendlich

SNIPPET_TEXT:
  1. ---
  2. title: "RegExp-Kurs - R (stringr)"
  3. author: "tegula"
  4. date: '2022-07-07'
  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 als "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 und der vordefinierten Zeichenklasse; siehe weiter unten) in der Regel übernommen werden.
  19.  
  20. # Installation
  21. R und die für den Kursteil benötigten R-Packages sind in den offiziellen Debian-Quellen verfügbar. Benötigt werden r-recommended und r-cran-tidyverse.
  22.  
  23. 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>.
  24.  
  25. # Besondersheiten von R
  26.  
  27. ## Zuweisungsoperator
  28. 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.
  29. ```{r}
  30. library(magrittr)
  31. data(trees)
  32. # Zuweisung an Objekte: Sowohl "<-" als auch "=" sind erlaubt.
  33. volumen_kubikzoll = trees$Volume
  34. volumen_kubikzoll <- trees$Volume
  35. # Übergabe eines Schlüsselwortarguments an eine Funktion: Ausschließlich "=" ist erlaubt.
  36. summary(object = volumen_kubikzoll, digit = 4)
  37. ```
  38.  
  39. ## Pipe-Operator
  40. 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.
  41. ```{r}
  42. library(magrittr)
  43. data(mtcars) # Beispieldatensatz (ist in R enthalten) laden
  44.  
  45. # 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.
  46.  
  47. ## Variante 1: Mit Klammern (ohne Pipe-Operator) --> IMHO eher unübersichtlich
  48. paste((as.character(multiply_by(mtcars$hp, 0.746))), "kW", sep = " ")
  49. ## Variante 2: Mit Pipe-Operator (in einer Zeile) --> IMHO schon übersichtlicher
  50. mtcars$hp %>% multiply_by(0.746) %>% as.character %>% paste("kW", sep = " ")
  51. ## Variante 3: Mit Pipe-Operator (in mehren Zeilen --> IMHO noch mal  übersichtlicher
  52. mtcars$hp %>%
  53.   multiply_by(0.746) %>%
  54.   as.character %>%
  55.   paste("kW", sep = " ")
  56. ```
  57. Weitergehende Infos zum Pipe-Operator (für die das Verstädnis/Bearbeitung dieses Kurs-Parts _nicht_ notwendig): <https://magrittr.tidyverse.org>
  58.  
  59. ## Escaping
  60. 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.
  61.  
  62. ```{r}
  63. library(tidyverse)
  64. # TODO: Es soll nur die Schreibweise mit zwei getrennten Wörter ("hallo debianforum") gefunden werden.
  65. ## richtig:
  66. "hallo_debianforum hallo debianforum" %>%
  67.   str_extract_all(pattern = "hallo\\b.debianforum")
  68. ## falsch:
  69. "hallo_debianforum hallo debianforum" %>%
  70.   str_extract_all(pattern = "hallo\b.debianforum")
  71. ```
  72.  
  73. Weitergehende Infos: <https://raw.githubusercontent.com/rstudio/cheatsheets/main/strings.pdf> (Seite 2, linke Spalte "Need to Know").
  74.  
  75. # Übersicht über die in stringr möglichen regulären Ausdrucke
  76. 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>. Ein auffälliger Unterschied zu egrep (ERE) besteht darin, dass auch _vordefinierte_ Zeichenklassen nur in einfache (statt doppelte) eckige Klammern gesetzt werden.
  77. ```{r}
  78. library(tidyverse)
  79. # Nur Elemente der vordefinierten Zeichenklasse "[:digit:]" (Zahlen) extrahieren
  80. "Die folgende Zahl lautet 9 (in Worten: Neun)." %>%
  81.   str_extract_all(pattern = "[:digit:]")
  82. ```
  83. # Funktionen im stringr-Package
  84. Der Überblick über die in stringr enthaltenen regex-Funktionen ist in der Vignette "Introduction to stringr" zu finden: <https://stringr.tidyverse.org/articles/stringr.html#pattern-matching>. Eine ausführliche Beschreibung findet sich in der Befehlsreferenz des stringr-Packages: <https://cloud.r-project.org/web/packages/stringr/stringr.pdf>.
  85.  
  86. # Vorbereitung
  87.  
  88. ## Arbeitsverzeichnis festlegen, Script-Datei erstellen und Schwäbische Kunde downloaden:
  89. 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 nun das R-Skript und fügt folgenden Befehl ein, um das Arbeitsverzeichnis festzulegen.
  90. ```{r eval=FALSE}
  91. #!/usr/bin/env Rscript #optional
  92. setwd(~/regex_R) # Arbeitsverzeichnis festlegen (Pfad ggf. anpassen)
  93. getwd()          # Arbeitsverzeichnis anzeigen
  94. print("Das ist ein Test") # Zeichenkette "Das ist ein Test" ausgeben
  95. ```
  96.  
  97. ## Skript ausführen (Ohne Entwicklungsumgebung):
  98. (Wenn ihr eine Entwicklungsumgebung zum Ausführen des Befehle bzw. eures Skripts nutzt, könnt ihr diesen Abschnitt überspringen.)  
  99. Öffnet ein Terminal, wechselt in eurer Arbeitsverzeichnis und übergebt das Script an das Programm Rscript. Daraufhin wird das Skript ausgeführt.
  100. ```{bash eval=FALSE}
  101. cd ~/regex_R # Pfad zum Arbeitsverzeichnis ggf. anpassen
  102. Rscript skript_regex.R # Pfad ggf. anpassen
  103.  
  104. ```
  105.  
  106. ## Schwäbische Kunde importieren und für spätere Verwendung abspeichern.
  107. 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.
  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. # Funktionen 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 soll ein Komma enthalten.
  129. schwaebische_kunde$is_match <- schwaebische_kunde$text %>%
  130.   str_detect(pattern = ",")
  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") # entspricht ...
  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. ## Vorkommen des Buchstabens e bzw. E in der jeweiligen Zeichenfolge (hier: Strophe der Schwäbischen Kunde)
  158. schwaebische_kunde$n_matches <- schwaebische_kunde$text %>%
  159.   str_count(pattern = "[eE]")
  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: str_extract
  193. ```{r}
  194. # Tidyverse laden
  195. library(tidyverse)
  196. # Schwäbische Kunde laden
  197. load("schwaebische_kunde.RData")
  198. # Regex-Funktion ausführen
  199. ## D
  200. schwaebische_kunde$first_match <- schwaebische_kunde$text %>%
  201.   str_extract(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. ```
  218.  
  219. ## Gruppen extrahieren (nur erstes match): str_match
  220. ```{r}
  221. # Tidyverse laden
  222. library(tidyverse)
  223. # Schwäbische Kunde laden
  224. load("schwaebische_kunde.RData")
  225. # Regex-Funktion ausführen
  226. ## Extrahiere das Wort vor dem ersten Komma oder Punkt
  227. schwaebische_kunde$text %>%
  228.   str_match(pattern = "([:alnum:]*)[:blank:]*[.,].*")
  229. ```
  230.  
  231. ## Gruppen extrahieren (alle matches): str_match_all
  232. ```{r}
  233. # Tidyverse laden
  234. library(tidyverse)
  235. # Schwäbische Kunde laden
  236. load("schwaebische_kunde.RData")
  237. # Regex-Funktion ausführen
  238. ## Extrahiere alle Kleinbuchstaben, die auf einen Großbuchstaben folgen
  239. schwaebische_kunde$text %>%
  240.   str_match_all("[:upper:]([:lower:])")
  241. ```
  242.  
  243. ## (Komplette) Zeichenkette zurückgeben, wenn mindestens ein Match enthalten ist: str_subset
  244. ```{r}
  245. # Tidyverse laden
  246. library(tidyverse)
  247. # Schwäbische Kunde laden
  248. load("schwaebische_kunde.RData")
  249. # Regex-Funktion ausführen:
  250. ## Zeichenfolgen (Zeilen), die ein Komma enthalten
  251. schwaebische_kunde$text %>% str_subset(pattern = ",")
  252. ```
  253.  
  254. ## Ersetzen (nur erstes Match ersetzen): str_replace
  255. ```{r}
  256. # Tidyverse laden
  257. library(tidyverse)
  258. # Schwäbische Kunde laden
  259. load("schwaebische_kunde.RData")
  260. # Regex-Funktion ausführen:
  261. ## Ersetze das erste Auftreten von "ae" durch "ä"
  262. schwaebische_kunde$text <- schwaebische_kunde$text %>%
  263.   str_replace(pattern = "ae",
  264.               replacement = "ä")
  265. # Ergebnis ausgeben
  266. schwaebische_kunde %>%
  267.   print(n = Inf)
  268. ```
  269.  
  270. ## Ersetzten (alle Matches ersetzen): str_replace_all
  271. ```{r}
  272. # Tidyverse laden
  273. library(tidyverse)
  274. # Schwäbische Kunde laden
  275. load("schwaebische_kunde.RData")
  276. # Regex-Funktion ausführen:
  277. ## Ersetze alle Leerzeichen durch Unterstriche
  278. schwaebische_kunde$text <- schwaebische_kunde$text %>%
  279.   str_replace_all(pattern = "[:space:]",
  280.                   replacement = "_")
  281. # Ergebnis anzeigen
  282. schwaebische_kunde %>%
  283.   print(n = Inf)
  284. ```
  285.  
  286. # Aufgaben
  287. 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").
  288. 2. Bestimme, wie viele Verse (Zeilen) der Schwäbischen Kunde mit einem Vokal (Selbstlaut) beginnen.
  289. 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).
  290. 4.) Extrahiere aus der Schwäbischen Kunde alle Großbuchstaben. Formatiere die Ausgabe so, dass getrennt nach Versen (Zeilen) folgende Informationen möglichst übersichtlich angezeigt werden: 1.) Zeilennummer des Verses. 2.) Gesamter Text des Verses. 3.) Alle Großbuchstaben, die in diesem Vers enthalten sind. Du bist frei in der Wahl des Ausgabemediums (z. B. R-Konsole, Standardausgabe, Spreadsheet-Datei oder ähnliches).
  291. 5.) Denke Dir selbst eine Aufgabe für die anderen Teilnehmer dieses Kursteils aus.
  292. 6.) Löse die Aufgaben der anderen Teilnehmer.
  293.  
  294. 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 :).
  295.  

Quellcode

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