Kurz: for (i in 1:3) cat(“i =”, i, “\n”) for (name in c(“Mia”, “Tom”)) cat(“Hallo”, name, “\n”)
Teil des Kurses R
if, else, Schleifen
x <- 7
if (x > 5) {
print("groß")
} else if (x > 2) {
print("mittel")
} else {
print("klein")
}
y <- if (x %% 2 == 0) "gerade" else "ungerade"
y
for (i in 1:3) cat("i =", i, "\n")
for (name in c("Mia", "Tom")) cat("Hallo", name, "\n")
n <- 3
while (n > 0) { cat(n, ""); n <- n - 1 }
cat("\n")
i <- 0
repeat { i <- i + 1; if (i == 2) next; if (i > 4) break; cat(i, "") }
cat("\n")
switch("b", a = "Apfel", b = "Birne", "unbekannt")
switch(2, "eins", "zwei", "drei")Ausgabe:
[1] "gro\303\237"
[1] "ungerade"
i = 1
i = 2
i = 3
Hallo Mia
Hallo Tom
3 2 1
1 3 4
[1] "Birne"
[1] "zwei"Hinweis
Für
ifmit Vektoren nutzeifelse(bedingung, ja, nein),iferwartet genau einen Wahrheitswert. In R vermeidest du Schleifen oft durch Vektorisierung undsapply.
zahlen <- 1:10
# Schleife
quadrate <- numeric(length(zahlen))
for (i in seq_along(zahlen)) quadrate[i] <- zahlen[i]^2
# Vektorisiert (besser):
identical(quadrate, zahlen^2)
sapply(1:5, function(i) i * 10)
Reduce(function(a, b) a * b, 1:6)
vapply(c("a", "bb", "ccc"), nchar, integer(1))Ausgabe:
[1] TRUE
[1] 10 20 30 40 50
[1] 720
a bb ccc
1 2 3Funktionen
quadrat <- function(x) x^2
gruss <- function(name = "Welt", laut = FALSE) {
text <- paste0("Hallo, ", name, "!")
if (laut) text <- toupper(text)
text # letzter Ausdruck = Rückgabewert
}
statistik <- function(x, na.rm = TRUE) {
list(mittel = mean(x, na.rm = na.rm), sd = sd(x, na.rm = na.rm), n = sum(!is.na(x)))
}
summe_alle <- function(...) sum(...)
optionen <- function(...) names(list(...))
quadrat(7)
gruss()
gruss("Mia", laut = TRUE)
statistik(c(2, 4, 4, 4, 5, 5, 7, 9))$mittel
summe_alle(1, 2, 3, 4)
optionen(farbe = "rot", groesse = 3)
(function(x) x + 1)(41)
sapply(1:3, \(i) i * 2) # Kurzschreibweise \(x) seit R 4.1
fakultaet <- function(n) if (n <= 1) 1 else n * fakultaet(n - 1)
fakultaet(10)
args(gruss)
is.function(gruss)Ausgabe:
[1] 49
[1] "Hallo, Welt!"
[1] "HALLO, MIA!"
[1] 5
[1] 10
[1] "farbe" "groesse"
[1] 42
[1] 2 4 6
[1] 3628800
function (name = "Welt", laut = FALSE)
NULL
[1] TRUER wertet Argumente lazy aus und kopiert Werte: Eine Funktion kann Variablen der Außenwelt nicht ändern (außer mit <<-).
Gültigkeitsbereich, Closures und Fehler
zaehler <- function() {
n <- 0
function() { n <<- n + 1; n } # <<- ändert die äußere Variable
}
z <- zaehler()
z(); z(); z()
sicher_teilen <- function(a, b) {
if (b == 0) stop("Division durch null")
a / b
}
ergebnis <- tryCatch(sicher_teilen(1, 0),
error = function(e) paste("Fehler:", conditionMessage(e)),
finally = cat("aufgeräumt\n"))
ergebnis
tryCatch(as.integer("x"), warning = function(w) paste("Warnung:", conditionMessage(w)))
res <- try(log(-1), silent = TRUE)
res
inherits(try(stop("x"), silent = TRUE), "try-error")
stopifnot(is.numeric(1), 1 + 1 == 2)
tryCatch(stopifnot("x muss positiv sein" = -1 > 0), error = function(e) conditionMessage(e))Ausgabe:
[1] 1
[1] 2
[1] 3
aufgeräumt
[1] "Fehler: Division durch null"
[1] "Warnung: NAs introduced by coercion"
[1] NaN
[1] TRUE
[1] "x muss positiv sein"Merke
if/else,for,while,repeat,switch;ifelsefür Vektoren- Funktionen:
function(x, y = 1) { ... }; letzter Ausdruck ist der Rückgabewert;...für beliebige Argumente - Vektorisierung und
sapply/vapplystatt Schleifen <<-ändert äußere Variablen,tryCatchfängt Fehler und Warnungen
Übungsaufgabe
Schreibe eine Funktion zusammenfassung(x), die Mittelwert, Median, Minimum und Maximum als benannten Vektor zurückgibt.
Quiz zur Selbstkontrolle
Was liefert eine R-Funktion ohne return?
- Den Wert des letzten Ausdrucks (richtig)
- NULL
- Das erste Argument
- Einen Fehler
Wofür ist ifelse?
- Bedingung elementweise auf einen Vektor anwenden (richtig)
- Schleife
- Fehlerbehandlung
- Funktionsdefinition
Wie fängt man Fehler ab?
- tryCatch (richtig)
- try/except
- rescue
- on.error
Weiter im Kurs
Zurück: Data Frames
Weiter: Text, Datum und Dateien
Alle Kapitel: R im Überblick