R - Einführung in Datenverarbeitung (Teil 1) (Stefan Bosse) [5.2025] |
Die Übung führt in die programmatische Datenverarbeitung und Datenanalyse mit der R Programmiersprache in. Genau genommen wird aus Gründen der Vereinfachung und Handhabung de Dialekt R+ verwendet, der eine Untermenge von R implementiert, Ergänzungen (auch syntaktisch) besitzt, und an einigen Stellen vom offiziellen R abweicht. R+ ist in JavaScript geschrieben und kann in jedem Web Browser oder mit der Plattform node.js ausgeführt werden.
In dieser Übung werden grundlegende Konzepte der Datenverarbeitung, grundlegende Datentypen und Funktionen eingeführt, die für datengetriebene Modellierung sehr nützlich sind und einen schellen Einstieg in die automatische Schadensdiagnostik mit Maschinellen Lernen ermöglichen soll.
Bitte folgenden Code ausführen um notwendige Bibliotheken zu laden. Nicht erforderlich bei nativer R Software.
use
eingebaut und steht dann mit allen seinen Funktionen direkt zur Verfügung. print
Funktion ausgeben.
▸
[] |
✗
≡
|
In der Datenanalyse und der Datenverarbeitung kommen Daten verschiedenster Typen und Strukturen vor. Man unterscheidet skalare Werte wie zahlen, Boolesche Werte, und i.A. auch Textzeichenketten (obwohl eigentlich nicht atomar da aus Textzeichen zusammengesetzt), und zusammengesetzte Werte wie Vektoren und Listen.
Eine Variable ist in R eine Referenz auf Werte. Werte können sein:
numeric
logical
mit den konstanten Werten TRUE
und FALSE
character
(sind unveränderlich, daher quasi skalar)vector
(Werte mit Reihenfolge numeric
ist tatsächlich gleich einem vektor mit einem Element - alle Werte sind Vektoren) ⇒ Startindex ist 1list
(Werte mit! Reihenfolge, aber nicht numerisch indiziert)array
(mehrdimensional)matrix
(zweidimensional)function
Variablen kann ein neuer Wert (also eine Referenz) zugewiesen werden mit den <-
und =
Operationen. Der Pfeiloperator sollte bevorzugt verwendet werden, der Unterschied zwischen beiden ist marginal, wobei =
noch für benannte Funktionsparameter verwendet wird. Ausdrücke können beliebig komplex sein, teils aus Operanden mit unterschiedlichen Datentypen bestehen. Innerhalb von Funktionen können "globale" Variablen nur mit dem <--
Operator verändert werden!
▸
[] |
✗
≡
|
Variablenamen können aus den Zeichen a
-z
, A
-Z
, den Zahlen 0
-9
(außer an erster Stelle) und einem Punkt .
sowie einem Unterstrich _
bestehen.
data
und data.avg
haben keine Bindung. Aufgabe 1. Zerlege folgenden komplexen Ausdruck in eine Sequenz von einfachen (max. eine Operation) unter Zuhilfenahme einer minimalen Anzahl von weiteren Hilfsvariablen y.t1, y.t2 usw.
▸
[] |
✗
≡
|
eS50MSA9IGErYiAKeS50MSA9IHkudDEqeAp5LnQyID0geF4yCnkudDIgPSBjICogeS50Mgp5LnQxID0geS50MSArIHkudDIKeS50MiA9IGEvMgp5ID0geS50MS15LnQyCnByaW50ICh5KQo=
Alle Variablen werden in einem globalen Arbeitsbereich (Kontext, Workspace) angelegt, der bereits vordefinierte Werte enthält. Innerhalb von Funktionen existiert ein lokaler Kontext und Arbeitsbereich, und Variablenzuweisungen finden in diesem statt. Funktionsparameter sind immer lokal (Funktionen werden weiter unten eingeführt).
Werte von Variablen und konstante Werte können mit der print()
oder logg()
Funktion auf der Konsole ausgegeben werden. Die logg Funktion gibt zusätzlich den Ausdruck aus dessen Wert ausgegeben wird. In R+ kann alternativ auch die cprint()
Funktion verwendet werden die zusammengesetzte Daten kompakter ausgibt.
Alle Funktionen geben nur einen Wert aus. Will man mehere Werte in einer Zeile ausgeben muss man die paste()
Funktion verwenden.
▸
[] |
✗
≡
|
In Datentabellen werden Metadaten und kategorische Werte häufig als Textzeichenketten abgelegt. Konstante Zeichenketten werden mit der "ABC"
Syntax eingeführt. Zeichenketten können mit der paste
Funktion zusammengeführt werden (jeweils mit Trennzeichen):
Folgende Basisoperationen existieren:
abbreviate
liefert eine Abkürzung einer Zeichenkettechartr(old,new,x)
ersetzt einen oder mehrere Zeichen in einer Zeichenkette (Ergebnis wird in einer Liste zurückgegeben)gsub(pattern,replace,text)
sucht nach Zeichenketten in text mittels eines regulären Ausdrucks (pattern) und ersetzt alle gefundenen Textstücke mit replace paste(str1,str2,..,sep="string")
fügt alle Argumente zusammen und verbindet sie mit einem Separator(Standard: Leerzeichen).strsplit(x,split)
zerlegt eine Zeichenkette in eine Liste von Tokenssubstr(x,start,stop)
liefert eine Teilzeichenkette beginnend bei start und bis stop (Zeichenposition, erstes Zeichen ist Position 1)tolower
wandelt alle Zeichen auf Kleinschreibung umtoupper
wandelt alle Zeichen auf Großschreibung umFunktionen erwarten Argumente in der Reihenfolge der Parameterdefinition, z.B. foo(a,b,c) erwartet als erstes Argument a, dann b, d.h., foo(1,2,3). Alternativ können die Argumente auch den Parameternamen zugewiesen werden, wo die Reihenfolge dann keine Rolle mehr spielt, also z.B. foo(c=3,a=1,b=2)
▸
[] |
✗
≡
|
Aufgabe 2. Zerlege die Zeichenkette "A-1 B-2 C-1" in Abschnitte die durch ein Leerzeichen getrennt sind (verwende strsplit
). Die Zerlegung von Zeichenketten liefert eine Liste. Iteriere dann über die Liste der Abschnitte (Listeniteration mit for
Schleife, siehe Beispiel) und entferne in jeder Teilzeichenkette den Bindestrich und die Ziffer indem strsplit
mit dem Bindestrich als Trennmuster nochmals angewendet wird. Einzelne Listenelemente können mit dem l[[index]]
Operator selektiert werden. Der erste Element einer Liste hat den Index 1.
▸
[] |
✗
≡
|
cy50b2tlbnMgPSBzdHJzcGxpdChzLCIgIikKbG9nZyhzLnRva2VucykKZm9yICh0b2tlbiBpbiBzLnRva2VucykgewogIG5hbWUgPSBzdHJzcGxpdChpLCItIilbWzFdXQogIHByaW50KG5hbWUpCn0=
Listen sind geordnete Werte die entweder über einen numerischen Index oder über einen Elementnamen und dem $
Operator referenziert werden können. Listen werden mit der list
Funktion erzeugt. Ein numerischer Selektor wird durch den [i]
Operator eingeleitet.
Achtung: l sei eine Liste. Im Unterschied zu (mathematischen) Vektoren liefert dann l[i]
hier wieder eine Liste mit einem Element! Will man das Listenelement direkt lesen verwendet man den Doppelklammer l[[i]]
Operator!
Benannte Listenelemente können bei der Erzeugung mittels name=val
erstellt werden, oder später durch die names
Funktion ergänzt werden. Listen können mehrsortig sein (d..h., Elemente von verschiedenen Datentyp). Neue Elemente können an einer bestimmten Position mittels append
hinzugefügt werden.
Kurzschreibweise für initialisierte Listenerzeugung in R+: {x,y,z}
für unbenannte Listenelemente und {a=x,b=y,c=z}
für benannte Listenelemente.
Wichtige Operationen auf Listen:
push(l,e)
append(l1,l2,..)
head(l,n)
. Standard ist n=1.tail(l,n)
. Standard ist n=1.as.vector(l)
names(l)
▸
[] |
✗
≡
|
lapply(Liste,Funktion)
Funktion.
▸
[] |
✗
≡
|
Eine Iteration über Listen (und Vektoren) kann auch mittels der for(v in l) { }
erfolgen. Hier ist v der Werte eines Listenelements (nicht der Name oder Index)! Listeniteration kommen häufig im Bereich Datenanalyse vor.
Aufgabe 3. Für Fortgeschrittene: Zerlege die Zeichenkette "A-1 B-2 C-1" wieder in Tokens die durch Leerzeichen getrennt sind. Dann transformiere diese Liste von Elementen mit lapply
derart dass die Ziffern hinter dem Bindestrich als nuemrischer Wert exrahiert wird (benutze wieder strplit
wie oben). Eine Zeichenkette kann in einen numerischen Wert mittesl as-numeric(string)
umgewandelt werden,
▸
[] |
✗
≡
|
cyA9ICJBLTEgQi0yIEMtMyIKIyAxLiBUcmVubnVuZyBkdXJjaCBMZWVyemVpY2hlbiA9PiBBIEIgQwpzLnBhcnRzID0gc3Ryc3BsaXQocywiICIpCiMgMi4gVHJhbnNmb3JtYXRpb24Kcy5udW1iZXJzID0gbGFwcGx5KHMucGFydHMsZnVuY3Rpb24gKHMpIHsKICB0b2tlbnMgPSBzdHJzcGxpdChzLCItIikKICBhcy5udW1lcmljKHRva2Vuc1tbMl1dKQp9KQoKbG9nZyhzLm51bWJlcnMp
Vektoren sind ähnlich den Listen aufgebaut. Vektoren bieten anders als Listen die Möglichkeit Werte in kompakten (linearen) Arrays zu speichern (optional, über ein mode Attribute bei der Erzeugung einstellbar). Daher kann ein bestimmter Datentyp (mode) angegeben werden. Ein von einer statischen Argumentenliste initialisierter Vektor wird mit c
, ein konstant initialisierter mit vector
erzeugt. Vektoren sind immer eindimensional. Mehrdimensionale "Vektoren" sind Arrays und Matrizen (zweidimensional), Teilbereiche eines Vektors können durch den Bracketoperator ausgewählt werden: v[index]
. Der Startindex ist wieder 1.
Folgende Vektorfunktionen sind wichtig:
length
min
, max
, range
, mean
, sum
v12 = v1 + v2
fivenum
; liefert {min, quantile1, median, mean, qunatile3, max} bei numerischen Vektorentable
bei kategorischen Vektoren
▸
[] |
✗
≡
|
Kurzschreibweise für initialisierte Vektorerzeugung in R+: [x,y,z]
.
Aufgabe 4. Analysiere die folgenden Vektoren klassengerecht (metrisch versa kategorisch), notiere die Ergebnisse. Was bedeuten die statistischen Werte? Führe eine Recherche durch.
fivenum
, summary
, und table
für beide vektoren)
▸
[] |
✗
≡
|
vn <- c(100,5,99,-4,100,110,55) vs <- c("a","b","a","c","a","b","b") logg(fivenum(vn)) logg(...
Zeitserien von Sensorsignalen werden häufig als Vektoren gespeichert. Ein Beispiel ist nachfolgend gezeigt. Es werden typische Analysefunktionen angewendet und ein grafischer Plot erzeugt.
▸
[] |
✗
≡
|
Frage 5. Was ist der Unterschied einer einfachen Datenserie (hier s) zu einer Zeitserie (oder abhängigen Datenserie) s(t)? Vergleiche die beiden Plots.
▸
[] |
✗
≡
|
Numerische Berechnung des Integrals einer Datenserie
Frage 6. Berechne das approximierte Integral der Datenserie und der Zeitserie. Die erste Berechnung ist einfach und trivial, die zweite benötigt eine Iteration über s und t mittels for(i in 1:length(s)) { .. }
.
▸
[] |
✗
≡
|
cy5pbnRlZ3JhbCAgID0gMApzLnQuaW50ZWdyYWwgPSAwCmZvciAoIGkgaW4gMTpsZW5ndGgocykpIHsKICBzLmludGVncmFsID0gcy5pbnRlZ3JhbCArIHNbaV0KfQpzLmludGVncmFsID0gcy5pbnRlZ3JhbCAvIGxlbmd0aChzKQpmb3IgKCBpIGluIDE6KGxlbmd0aChzKS0xKSkgewogIHMudC5pbnRlZ3JhbCA9IHMudC5pbnRlZ3JhbCArIHNbaV0qKHRbaSsxXS10W2ldKQp9CmxvZ2cocy5pbnRlZ3JhbCxzLnQuaW50ZWdyYWwp
Eine Matrix (ähnlich einem Datenrahmen, folgendes gilt i.A. auch für Datenrahmen) ist eine zweidimensionale Tabelle und wird mit der matrix(init,nrow,ncol)
Funktion erzeugt. Der Datentyp muss skalar bzw. atomar sein (numeric
, logical
, `character').
Folgende Matrixfunktionen sind wichtig:
col(m)
liefert eine Matrix von m mit Spaltenindexwertendiag(m)
liefert die Diagonalelemente einer Matrixdim(m)
liefert die Dimensionen einer Matrixrow(m)
liefert eine Matrix von m mit Zeilenindexwertennrow
, ncol
, colnames
um einzelne Informationen über die Matrix zu erhaltenmin
, max
, range
, mean
, sum
%*%
cbind
fügt Vektoren (oder Matrizen) spaltenweise an Matrizen (oder Vektoren). Ergebnis ist eine erweiterte Matrixrbind
fügt Vektoren (oder Matrizen) zeilenweise an Matrizen. Ergebnis ist eine erweiterte Matrixapply(m,MARGIN=[1,2],function(v,i,j))
oder map(m,function(v,i,j))
verwendet.Bei der Auswahl von Elementen einer Matrix gibt es jetzt mehr Möglichkeiten. Ein einzelnes Matrixelement wird mittels
m[row,col]
ausgewählt, eine Zeile durchm[row,]
, und eine Spalte durchm[,col]
. Es können auch Teilmatrizen gebildet werde:m[row1:row2,col1:col2]
, und Kombinationen aus allen Selektoren.
Frage 7. Es gibt noch weitere nützliche Funktionen wie col
und row
. Untersuche im folgenden Beispiel diese Funktionen. Was ergibt die Anwendung dieser beiden Funktionen auf Matrizen?
▸
[] |
✗
≡
|
row(matrix)
und col(matrix)
erzeugen eine gleich große Matrix gefüllt mit den Spalten und Zeilen Indizes.==
angewendet auf zwei Matrizen ergibt eine Boolesche Matrix mit Einträgen die den elementweisen Vergleich enthaltenFrage 8. Was ist der Unterschied bei der Initialisierung von data1 und data2? Was passiert wenn anstelle 1:15
der Bereichsvektor 1:3
verwendet wird? Prüfe es praktisch.
1:15
füllt die Matrix vollständig (gleiche Anzahl von Elementen)
▸
[] |
✗
≡
|
cbind(col1,col2,..)
Funktion
▸
[] |
✗
≡
|
Aufgabe 9. Berechne den Mittelwert aller Elemente einer Matrix mit Schleifen.
▸
[] |
✗
≡
|
bSA8LSBtYXRyaXgocnVuaWYoMTUpLDUsMykKbS5tZWFuIDwtIDAKZm9yIChpIGluIDE6bnJvdyhtKSkgewogIGZvciAoaiBpbiBuY29sKG0pKSBbCiAgICBtLm1lYW4gPSBtLm1lYW4gKyBtW2ksal0KICB9Cn0KbS5tZWFuID0gbS5tZWFuIC8gbGVuZ3RoKG0ubWVhbikKbG9nZyhtLm1lYW4p
v[i]
sowohl lesend als auch schreibend ausgewählt werden.l[[i]]
verwendet werden um an das Listenelement zu gelangenv$x
refernziert werden[a:b]
Operator mit index={a,a+1,..,b} ausgewählt werden[row,col,..]
referenziert werden
Arithemtische (+
, -
, *
, /
, %
, %%
), relationale (<
, >
, >=
, <=
, ==
, !=
) und logische (&
, |
) Operationen können auf einer Vielzahl von Datentypen inklusive Aggregationen wie Listen und Vektoren direkt angewendet werden. Bei Listen und Vektoren werden diese Operationen elementweise angewendet und erzeugen einen neuen Vektor.
▸
[] |
✗
≡
|
Aufgabe 10. Zerlege und analysiere den primes[primes>5]
Ausdruck. Was liefert primes>5
und wie funktioniert die Reduktion (Filterung) des Vektors? Erstelle einen Teilvektor aus primes der nur Werte < 5 und Werte > 10 enthält.
▸
[] |
✗
≡
|
primes>5
liefert einen Booleschen Vektor der wiederum in der Indizierung zur Reduktion des ursprünglichen Vektors eingesetzt wirdlogg(primes[primes>5])
und logg(primes[primes<5])'
primes.part = c(primes[primes<5],primes[primes>10])
Aufgabe 11. Skaliere im nachfolgenden Beispiel die x Spalte der Matrix auf ihren Maximalwert (d.h. Normierung auf 1). Benutzte den m[,2]
Selektor und die max
Funktion.
▸
[] |
✗
≡
|
Bei der datengtriebenen Modellierung spielen statistische und (pseudo)randomisierte Prozesse eine wichtige Rolle. Es gibt primär zwei wichtige Wahrscheinlichkeitsverteilungen und Funktionen:
Es stehen im math Modul dafür zwei Funktionen zur Verfügung:
runif(n,min,max)
, Standardwerte für das Werteintervall sind [0,1] mit einem Mittelwert von 0,5rnorm(n,min,max)
, Standardwerte für das Werteintervall sind [-1,1] mit einem Mittelwert von 0Die Gleichverteilung benutzt man häufig um zufällig kontinuierliche Werte aus einem Wertebereich auszuwählen. Die Normalverteilung wird häufig für die Erzeugung von synthetischen Rauschen und in der Monte Carlo Simulation eingesetzt.
Will man künstliches Rauschen (Variation) zu bereits existierenden Sensorwerten hinzufügen muss man unterscheiden ob es sich um additives oder multiplikatives Rauschen handelt.
Bei multiplikativen Rauschen sollte der Mittelwert des Rauschfaktors bei 1 liegen, bei additiven Rauschen bei 0!
hist
Funktion kann sich das Histogramm der Wertevereilung berechnen und anzeigen lassen.Aufgabe 12. Untersuche im nachfolgenden Beispiel die Wirkung von normal- und gleichverteilten Rauschen sowohl multiplikativ als auch additiv. Wo liegen messtechnisch und physikalisch die Unterschiede dieser 4 Kombinationsmöglichkeiten? Wähle ca. 10% Rauschanteil. Neben einer Sinusfunktion soll auch der Einfluss von Rauschen auf eine lineare Werteverteilung (also einfach eine Sequenz x=1:100
) betrachtet und visualisiert werden.
▸
[] |
✗
≡
|