---
title: "R Einführung"
output:
  pdf_document: default
  html_document: default
---

In diesem Markdown-Dokument lernen wir die Grundlegenden Funktionen der Statistiksoftware R kennen. Hierbei werden wir die folgenden Kapitel behandeln:

1.  Datentypen
2.  Packages
3.  Funktionen
4.  Schleifen und Bedingungen
5.  Zufallszahlen
6.  Plotten
7.  Data Frames


Am besten öffnest du ebenfalls ein R Skript und wandelst die aufgeführten Beispiele nach Lust und Laune ab. 

Da es laut [Wikipedia](https://de.wikipedia.org/wiki/Hallo-Welt-Programm#Geschichte) Tradition ist, starten wir auch diese Einführung mit einem "Hello World!" Programm.

```{r}
print("Hello World!")
```

# 1. Datentypen

In R gibt es die üblichen Datentypen:

  - Integer
  - Double
  - Complex
  - Character (String)
  - Logical (Boolean)
  - Raw
  
Wobei jedoch Raw sehr selten benutzt wird und deshlab hier nicht wirklich behandelt wird.


## Grundlegendes

Mit `typeOf()` oder `classOf()` kann der Datentyp eines Objektes ausgegeben werden.
Per default sind alle "Zahlen" als double gespeichert, können jedoch mit einem "L" zu einem Integer umgewandelt werden.
Strings werden mit `" "` oder `' '` erstellt.

```{r}
typeof(42)
typeof(42L)
class(42L)
typeof(42.0)
typeof("Zweiundvierzig")
typeof('Zweiundvierzig')
typeof(TRUE)
typeof(4+2i)
charToRaw("Zwei und Vierzig")
typeof(charToRaw("Zwei und Vierzig"))
```


Mit `#` wird ein Kommentar markiert, d.h. der Interpreter ignoeriert was nach # kommt.

```{r}
# wichtige Inforamtion zum Verstehen des Codes
```


Selbstverständlich können Werte auch in Variablen gespeichert werden. Dies geschieht mit `=` oder `<-`, wobei letzteres geläufiger ist.
    
Durch `x<-3` wird eine Variable x mit dem Wert 3 erstellt. Durch einfassen in Klammern, `(x<-3)` wird die Variable direkt ausgegeben. Dies ist äquivalent zu `x` in einem Codeblock. Mit `print(x)` werden ebenfalls Konsolenausgaben erzeugt.


```{r}
x<-3       # keine Ausgabe
(x<-3)     # Ausgabe
x          # Ausgabe
print(x)   # Ausgabe
```

Für numerische Datentypen funktioneren die Grundrechenarten wie zu erwarten. Der Modulo-Operator wird in R mit `%%` aufgerufen und mit `%/%` wird ganzzahlig geteilt.

```{r}
3+3
16-4
7*9.1
4/2

5%%2
3%/%2
3%/%4
```

Logicals nehmen die Werte `True` und `FALSE`an und können mit `T` bzw. `F` abgekürzt werden.
Wie üblich werden sie mit `x & y`, `x | y`, ` ! x` sowie `xor(x,y)` verarbeitet. Mit `isTRUE()` bzw. `isFALSE` lässt sich der Zustand des Boolens abfragen. 

Hier ist jedoch die Besonderheit zu beachten, dass bei der Verwendung von Vektoren (nächster Abschnitt) im Falle von ` & ` und  ` | ` wird der Operator elementweise interpretiert wird. 


```{r}
x<-TRUE
y<-FALSE
x&y
x|y
!x
xor(x,y)


isTRUE(x)
isFALSE(x)

c(T,T,T) & c(F,T,T)
c(T,T,T) & c(T,T,T)
```

Vergleichsoperatoren vergleichen zwei Objekte und liefern einen Boolen zurück. Für Skalare Zahlen sind in R die folgenden Operatoren definiert.

```{r}
1==1      #gleich
1!=1      #ungleich
1<2       #kleiner als
1>2       #größer als
1<=2      #kleiner oder gleich
1>=2      #größer oder gleich
```


## Vektoren und Matrizen

### Vektoren

Wie gerade schon angedeuted ist es selbstverständlich auch möglich Werte in Arrays zu speichern. Arrays sind ein, zwei oder n- dimensionale Objekte in denen sich mehrere Werte speichern lassen.
Aufgrund des mathematischen Schwerpunkts benutzen wir hier in dieser Einfühung die Worte Array und Vektor, bzw. 2D Array und Matrix synonym.
Mit der Funktion `c( )` können wir einen Vektor erstellen

```{r}
x<-c(1,2,3)
c(14,23,4)->z     #"Pfeilschreibweise" funktioniert auch in die andere Richtung
c(x,0,0,0,0,z)
```

Die oben beschriebenen Grundrechenarten können auch auch Vektoren angewendet werden und werden dabei elementweise verstanden.


```{r}
x+3
x+x
x+c(1,2) #c(1,2) ist kürzer als x, deshalb wird mit dem ersten Element wieder begonnen
```

Die grundlegenden Funktionen wie `log(),exp(),min(),sin(),..` sind in der R Basisversion bereits implementiert und lassen sich einfach auf Vektoren anwenden.
Besonders nützlich ist die Funktion `length()`, welche die Länge des Vektors ausgibt.
Inforamtionen zu Funktionnen können mit `help(sqrt), ?sqrt, ??sqrt` oder allgemein `help.start()` ausgegeben werden.

```{r}
sin(x)
log(x)
max(x)
length(x)
help(sqrt)
```

Vektoren mit Zahlenfolgen können so erzeugt werden

```{r}
1:10        #ganzzahlig von 1 bis 10
seq(from=0,to=5.7,by=0.3)    #von 0 bis 5,7 in Schritten der Größe 0,3
seq(0,0.5,0.1)               #analog ohne "from","to" und "by

rep(0,10)                    # 0 wird 10 mal wiederholt
rep(c(1,2),3)
rep(c(1,2,3),each=3)
rep(c(1,2,3), times=c(2,1,3))
```

Es gibt verschiedene Arten auf die Einträge von Vektoren zuzugreifen, z.B. über den Index, bzw. über Vektoren mit Indizes
(R indiziert ab 1, d.h. auf das erste Element eines Vektors wird mit 1 zugegriffen)

```{r}
x<-1:10
x[1]
x[c(1,3)]
```

Mit negativen Indizes lassen sich Werte aus Vektoren entfernen

```{r}
x<-1:10
x[-1]
x[-c(1,3,5)]
```

Auch mithilfe von logischen Vektoren lässt sich auf Elemente eines Vektors zugreifen. Dies vereinfacht den Zugriff auf Einträge mit gewissen Eigenschaften, z.B. alle durch zwei teilbaren Einträge. Hierbei wird nur auf Elemente zugegriffen bei denen der Indexvektor TRUE ist.

```{r}
x<-1:10
b<-rep(c(T,T,F,F,T),2)
x[b]
durchZweiTeilbar<-c(x%%2==0)
x[durchZweiTeilbar]=42
x
```

### Matrizen

Wie bereits erwähnt sind Matrizen zweidimensionale Arrays.

```{r}
(M<-matrix(1:9,nrow=3))
matrix(10:18,nrow=3,byrow=TRUE)
```

Und der Zugriff erfolgt entweder elementweise, oder spalten/zeilenweise

```{r}
M[1,2]
M[1,]
M[,1]
M[,c(1,3)]
M[c(1,2),c(1,3)]
```

Auch für Matrizen gibt es unzählige Rechenoperationen. Hier eine kleine Auswahl


```{r}
t(M) # Transponieren
M%*%M #Matrixmultiplikation


A<-matrix(c(1,2,1,2,5,-1,4,8,5),nrow=3)  
b<-c(1,1,1)

solve(A) #Invertieren
solve(A,b) #Löse: Ax=b

eigen(A) #Eigenwertzerlegung
```


# 2. Packages

Bis jetzt haben wir nur mit der Basisfunktion von R gearbeitet, jedoch gibt es unzählige Packages, die Funktionen und Datensätze enthalten.
Diese müssen einmalig mit dem Befehl `install.packages()` installiert werden und mit `library()` im Skript geladen werden. 
Im Laufe dieser Einführung werden wir noch einige nützlichen Packages kennenlernen.

```{r}
#install.packages("data.table")
library(data.table)
```

# 3. Funktionen

Durch Funktionen lassen sich gewisse Operationen leichter an verscheidenen Stellen ausführen und der Code wird dadurch überichtlicher. Definiert werden Funktionen in einer Funktionsumgebeung und können dann an einer beliebeigen Stelle im Skript aufgerufen werden.

Innerhalb einer Funktion können Variablen definiert werden, diese überschreiben keine gleichnamigen Variablen außerhalb der Funktion, außer dies wird mit einem ` <<- ` erzwungen.

Falls es lokal, innerhalb einer Funktion eine Variable nicht gibt, wird auf die globale Variable mit dem gleichen Namen zugegriffen.

Mit ` return() ` wird ein Wert zurück gegeben. Ohne das Stichwort return wird die letzte Zeile inerhalb der Funktion zurückgegeben.

```{r}
addieren <- function(a,b,c){
    a=a+b+c                    #ohne globales a zu überschreiben
    return (a) # mit return
}
   
addieren2 <- function(a,b,c){
    a+b+c #ohne return
}

ueberschreiben <- function(b){
    a<<-3 # überschreiben
    return ("Überschrieben")
}

globalerZugriff <- function (x){
    return( x+a ) # ohne, dass a übergeben oder in der Funktion definiert wurde
}
   
a<-1
addieren(a,2,3)
addieren2(1,2,3)
a

ueberschreiben(a)
a

globalerZugriff (4)
```

Bei der Übergabe können default Parameter festgelegt werden, die benutzt werden, sofern nichts anderes angegeben wird. 


```{r}
sinus <- function (x,ampl=1,shift=0){
    return (ampl*(sin(x-shift)))
    }

sinus(3)
sinus(3,1,0)
```

Außerdem kann die Reihenfolge der Inputparamter vertauscht werden, wenn diese mit ` = ` übergeben werden

```{r}
sinus2 <- function (x,ampl,shift) {
    return (ampl*(sin(x-shift)))
}

sinus2(3,2,1)
sinus2(3,shift=1,ampl=2)
```

Operatoren wie z.B. ` + ` sind auch Funktionen. Durch eine Verschachtelung des Funktionsnamens in ` "% %" ` lässt sich eine Funktion konstruieren, welcher eine Variable vor und eine nach dem Funktionsnamen übergeben wird.

```{r}
`%addmult2%` <- function(x,y) {
  x+2*y
  }

1:4 %addmult2% 3:6
```



# 4. Schleifen und Bedingungen

## 4.1 If - Bedingungen
Eine If Bedigung hat eine Boolean als Input und führt je nach Zustand eine Operation aus 

Die einfachste If- Bedingung hat die Gestalt

` if (Bedingung){ `

   ` Anweisung `
   
`}`

Dies lässt sich zu einem "Entweder, oder" erweitern

` if (Bedingung){`

  `  Anweisung `
  
`}else{`

  ` Anweisung alternativ`
    
`}`

Mit ` else if ` lassen sich mehrere Fälle abfragen, wobei immer der erste Fall der zutrifft eintritt

` if (Bedingung){`

  `  Anweisung `
  
`}else if (Bedinung 2){`

   ` Anweisung alternativ`
   
`}else{`

   ` Anweisung alternativ 2`
   
`}`


```{r}
x<-0

if (x<10){
    print("kleine Zahl")
}

if (x>10){
    print("große Zahl")
}else{
    print("kleine Zahl")
}

if (x>0){
    print("positiv")
}else if (x<0){
    print("negativ")
}else{
    print("Null")
}
```

Diese Art von If-Bedinung ist jedoch nur skalarwertig. Wollen wir Vektoren abfragen, können wir dies folgendermaßen machen

```{r}
x<- -2:10


ifelse(x>0,"positiv","Null oder negativ")
```


## 4.2 For Schleife

In einer for-Schleife läuft ein Zähler über jedes Element eines Vektors. In der Regel sind dies Integer von 1 bis n, da man so auf andere Vektoren und Matrizen zugreifen kann, doch ist es auch möglich über z.B. Doubles oder Logicals zu iterieren.

```{r}
frucht<-c('Apfel','Banane','Kiwi','Birne','Mango')

for (zähler in 1:length(frucht)){
    print(frucht[zähler])
}

for (count in seq(from=0.1,to=1,by=0.1))
    {
    print(count)
}

for (bool in c(T,T,T)){
    print("Iteration")
}
```


## 4.3 While-Schleife

Prinzipiell kann jede for-Schleife durch eine while-Schleife ersetzt werden und umgekehrt. Jedoch gibt es durchaus Anwendungen bei dennen das eine sinnvoller ist als das andere.

Eine while-Schleife wiederholt so lange einen Prozess,  bis eine Bedingung erfüllt ist.

```{r}
n<-0
while(n<5){
    print(n)
    n<-n+1
}

c<-1
bool<-T
while(bool){
    print("Yap")
    if (c==5){
        bool<-F
        }
    c<-c+1
}
```

## 4.4 Repeat-Schleife

Sehr ähnlich wie eine while-Schleife, ist eine repeat-Schleife. Diese wird mit dem Stichwort ` break ` beendet.

```{r}
n<-0

repeat{
    n<-n+1
    if(n==7) break
    if(n %% 2 == 0) print(n)
}
```

## 4.5 Exkurs: Vektorisieren

Schleifen sind oft sehr ineffektiv und langsam, deshalb werden Operationen vektorisiert um die Performance des Codes zu erhöhen. Z.B. wendet die Funktion ` apply(M,dim,fun) ` die function  ` fun ` zeilen- oder spaltenweise (dim=1,2) auf ` M ` an.

```{r}
(M<-matrix(1:9,nrow=3))

apply(M,1,mean)
apply(M,2,sum)
```

Dieses Prinzip kann auch mit ` lapply(x,fun) ` auf Listen übertragen werden.

```{r}
liste=list(Spaß=c("Fahrrad","Mathe","Party"),kleineZahlen=1:9,großeZahlen=12:18)
lapply(liste,length)
```

Kompliziertere Funktionen lassen sich entweder vorab definieren, oder mit sog. anonymen Funktionen auf Listen/ Matrizen/ ... anwenden.

Anonyme Funktionen wenden die Funktion auf jedes Element ` x ` der List/ Matrix/ ... an. Und werden entweder mit ` function(x) ... ` oder ` \ (x) ... ` initialisiert.

Mit der Funktion ` sapply(I,fun) ` kann auf auf jedes Element von I die Funktion angewandt werden. 

Der Unterscheid zwischen den Funktionen ist, dass ` apply(I,dim,fun) ` die Funktion spalten- oder zeilenweise anwendet, ` lapply(I,fun) ` elementweise anwendet, aber Listen zurückgibt und ` sapply(I,fun) ` ebenfalls elementweise anwendet, aber Vetoren/ Matrizen/ Listen zurückgibt.

```{r}
SehrNuetzlicheFunktion<-function(x){
    if (any(x>5)){
        return(x)
    }else{
        return("klein")
    }
}

print("apply()")
apply(M,2,SehrNuetzlicheFunktion) # Vordefinierte Funktion
print("sapply()")
sapply(M,SehrNuetzlicheFunktion)
print("lapply()")
lapply(M,SehrNuetzlicheFunktion)

print("Anonyme Funktionen")
lapply(liste,function(x) length(x)<4) # Anonyme Funktion
apply(M,2,\(x){if (any(x>5)){x}else{"klein"}}) # Das selbe wie oben, nur anonym
       
```

## 5  Zufallszahlen

Um Plots wie Histogramme oder Boxplots zu erklären, führen wir noch kurz die Generierung von Zufallszahlen ein.

Einer der wichtigsten Befehle ist hierbei ` runif(n) `, welcher einen Vektor mit n Zufallszahlen auf [0,1] erzeugt. Flexibler ist der Befehl ` sample(x,n,replace,prob) `, welcher n Elemente aus x zieht. Mit dem Boolean replace kann Zurücklegen aktiviert, bzw. deaktiviert werden. Mit dem Vektor prob kann die Wahrscheinlichkeit, dass ein Element gezogen wird gewichtet werden.

Alle am PC generierten Zufallszahlen sind nicht echt zufällig, siehe [Wikipedia](https://de.wikipedia.org/wiki/Pseudozufall). Sie werden mit einem Algorithmus berechnet und können nicht vom echten Zufall unterscheiden werden, jedoch können sie reproduziert werden, indem der selbe Startwert, der sog. Seed übergeben wird. Wird kein Seed übergeben wird bei R die Systemzeit als Seed benutzt.


```{r}
# Bei jeder Ausführung verscheidene zufällige Ergebnisse
(uniform<-runif(1))
(uniform2d<-runif(3))

(integer<-sample(1:10,10,replace=T))                # Ganzzahlig zwischen 1:100, mit zurücklegen, 
                                                    # ACHTUNG: defaul=F

(zufall<-sample(c("apfel","birne","melone"),1))     # Funktioniert auch für beliebige Mengen

(normalverteilt<-rnorm(n=3,mean=1,sd=2))
```

```{r}
# Bei jeder Ausführung die selben Ergebnisse
set.seed(43)
sample(1:10,1)
```


Es können auch Zufallszahlen nach bestimmten Verteilungen erzeugt werden

Diskret: - ` rpois(), rbinom(), ... ` 

Stetig: - ` rbeta(), rexp(), rnorm(), runif(),..  ` 

Hierbei wird immer erst die Anzahl der Zufallsvariablen übergeben und dann optional die jeweiligen Parameter der Verteilung.

```{r}
rpois(10,1000)
rexp(5,3)
```

# 6. Plotten

## 6.1 Lineplots, Scatterplots 
In R gibt es nur einen Befehl zum plotten, nämlich <code> plot(x,y,...) </code>. Es werden sämtliche (optionale) Parameter direkt mit übergeben:

  - type: (als String): 'n' - none, 'l' - line, 's' - stepfunction, 'p' - points (default)
  - xlim, ylim (als Vektor): Achsenabschnitte z.B. c(0,4.2)
  - main: (als String): Titel
  - xlab, ylab (als String): Achsenbeschriftungen
  - col: (als String) siehe. colours() oder (als Zahl) z.B: 2 = rot
  - pch (Zahl oder String): Markerymbol
  - cex (Zahl): Markergröße (character expansion)
  - lty (Zahl): Linetype - 1 = durchgezogen, 2 = gestrichelt...
  - lwd (Zahl): Lininedicke 

```{r}
x<-seq(from=0,to=2*pi,by=0.1)
y<-sin(x)

plot(x,y,main='Sinus',col=1,pch='+',cex=2)
plot(x,y,type='s',col=3,lwd=3)
```

Mit <code> lines() </code> oder <code> points() </code> lassen sich mehrere Muster in das selbe Bild einfügen.

```{r}
plot(x,y,main="Mehr Information",type='l',lwd=3,ylim=c(-0.8,1.5))
points(x,y+0.4,col=5,pch='^')
lines(x,y-0.4,col=8)
legend(4.5,1.2,c('Linie','Hüte','graue Linie'),col=c(1,5,8),lty=c(1,2,1))
```

Funktionen können auch direkte mit dem Befehl <code> curve </code> geplottet werden

```{r}
curve(sin,from=13.2,to=26)
```

Höhenlinien lassen sich mit <code> contour(x,y,z) </code> erstellen

```{r}
xs=seq(from=-5,to=5,by=0.1)
ys=seq(from=-5,to=5,by=0.1)
zs=sin(sqrt(outer(xs^2,ys^2,'+')))  # outer erstellt eine Matrix mit den passenden
                                    # Funktionswerten zu sqrt(x^2+y^2)

contour(xs,ys,zs,main='Höhenlinien')
filled.contour(xs,ys,zs,main='heatmap')
```

## 6.2 "Statistische" plots

Ohne viel zu erklären, hier ein paar Möglichkeiten Datensätze zu visualisieren.

```{r}
h<-c(rnorm(n=1000,mean=1,sd=1.5),rnorm(n=750,mean=7,sd=1))

hist(h,breaks=20,ylab='Häufigkeit',xlab='Kontostand in [€]',main='Histogramm',col='blue')

boxplot(rexp(1000),main='Boxplot',col='darkgreen')

i<-c(3,5,9,1)  # Zu Gruppe 1-4 gehören jeweils 3,5,9,1 Datenpunkte
label<-c('Apfel', 'Banane', 'Birne', 'Erdbeere') # Labels initialisieren

barplot(i,names.arg=label,col='red',main="Balkendiagramm")
``` 

Abschließend hier noch eine Möglichkeit einen erzeugten Plot zu speichern. Analog lassen sich Plots auch als andere Dateiformate speichern. 

```{r}
jpeg(file="Tortendiagramm.jpeg")                # Speichert als .jpeg ins aktuelle Arbeitsverzeichnis
                                                # Analoge Befehle existieren für .pdf, .png ,...
pie(i,labels=label,main='Mhhhhh....Torte')      # Bild erstellen
pdf(file="Tortendiagramm.pdf")                  # als .pdf 
pie(i,labels=label,main='Mhhhhh....Torte')      # Bild erstellen

```




## 7. Dataframes
Ein Data Frame ist eine Datenstruktur, die als Tabelle interpretiert werden kann, er besteht also aus Zeilen und Spalten. 
Alle Zeilen sind gleich lang und sind vom gleichen Datentyp. 
Alle Spalten sind gleich lang, aber verschiedene Spalten können unterschiedliche Typen haben. (siehe unten, z.B. Double und String)

Der Datansatz 'ToothGrowth' ist ein Beispiel Frame von R und enthält die Ergebnisse eines Experiments bei dem der Einfluss von Vitamin C auf das Zahnwachstum von Meerschweinchen untersucht wurde. 
Die Zeilen bilden Datenpunkte von 60 unterssuchten Meerschweinchen, während die Spalten die betrachteten Merkmale beschreiben: Länge der Zähne, Verabreichungsart (VC - ascorbine acid und OJ - Orangensaft), sowie die tägliche Vitamin C Dosis.

Hier ein paar Befehle, mit dennen ihr einen Data Frame untersuchen könnt
```{r}
(dim(ToothGrowth)) # Dimension

(head(ToothGrowth,3)) # Erste drei Zeilen des Datensatzes

(tail(ToothGrowth,3)) # Letze drei Zeilen des Datensatzes

(str(ToothGrowth))    # Aufbau

# Analog zu Matrizen, Zugriff auf bestimmte Einträge
(ToothGrowth[5,])     # 5. Zeile (-> Beobachtung)

(ToothGrowth[,2])     # 2. Spalete (-> Merkmal)

(ToothGrowth[2:4,c(1,3)])

# Zugriff über Name des Merkmals mit dem Operator $

(ToothGrowth$len)     # gibt alles Längen zurück
(ToothGrowth$len[1:5])   # Die ersten 5 Längen
(ToothGrowth$dose==0.5)     # Booleanvektor -> True an den Stellen dose==0.5
(ToothGrowth[ToothGrowth$dose==0.5,]) # Gibt alle Zeilen mit dose==0.5

```
Selbstverständlich wollen wir jetzt noch wissen, ob das Zahnwachsum mit der Vitamin C Dosis korreliert

```{r}
(cor(ToothGrowth$len,ToothGrowth$dose, method="pearson")) # Pearson Korrellationskoeffizient

(cor(ToothGrowth$len[ToothGrowth$supp=="OJ"],ToothGrowth$dose[ToothGrowth$supp=="OJ"], 
     method="pearson")) # Bedingt auf Orangensaft

(cor(ToothGrowth$len[ToothGrowth$supp=="VC"],ToothGrowth$dose[ToothGrowth$supp=="VC"], 
     method="pearson")) # Bedingt auf Vitamin C Präparat
```


