Welcome to R! In this section, you’ll learn the fundamental building blocks of R programming. Take your time with each exercise - understanding these basics thoroughly will make everything else easier.
How to use these exercises:
____ with the correct codeWillkommen bei R! In diesem Abschnitt lernst du die grundlegenden Bausteine der R-Programmierung. Nimm dir Zeit für jede Übung - wenn du diese Grundlagen gut verstehst, wird alles andere einfacher.
So verwendest du diese Übungen:
____ mit dem richtigen CodeConcept: Variables are containers that store values.
In R, we use <- to assign values to variables.
Konzept: Variablen sind Behälter, die Werte
speichern. In R benutzen wir <- um Werte zuzuweisen.
# Store the number 42 in a variable called "answer"
# Speichere die Zahl 42 in einer Variable namens "answer"
answer <- ____
print(answer)
# Store your age in a variable
# Speichere dein Alter in einer Variable
my_age <- ____
print(my_age)
# Store a decimal number (height in meters)
# Speichere eine Dezimalzahl (Größe in Metern)
my_height <- ____
print(my_height)
# Text variables - use quotes!
# Text-Variablen - benutze Anführungszeichen!
# Store your name (text needs quotes)
# Speichere deinen Namen (Text braucht Anführungszeichen)
my_name <- "____"
print(my_name)
# Store a species name
# Speichere einen Artnamen
species <- "____"
print(species)
# Logical variables - TRUE or FALSE
# Logische Variablen - TRUE oder FALSE
# Is it raining? (answer TRUE or FALSE, no quotes!)
# Regnet es? (antworte TRUE oder FALSE, keine Anführungszeichen!)
is_raining <- ____
# Is 5 greater than 3? (R can calculate this!)
# Ist 5 größer als 3? (R kann das berechnen!)
five_greater_three <- 5 > 3
print(five_greater_three)
# Is 10 equal to 10? (use == for comparison)
# Ist 10 gleich 10? (benutze == für Vergleich)
ten_equals_ten <- 10 ____ 10
print(ten_equals_ten)
# Is "oak" equal to "Oak"? (R is case-sensitive!)
# Ist "oak" gleich "Oak"? (R unterscheidet Groß/Kleinschreibung!)
oak_equals_Oak <- "oak" == "Oak"
print(oak_equals_Oak)
# Create two number variables
# Erstelle zwei Zahlen-Variablen
a <- 10
b <- 3
# Addition
sum_ab <- a ____ b
print(sum_ab) # Should be 13 / Sollte 13 sein
# Subtraction / Subtraktion
diff_ab <- a ____ b
print(diff_ab) # Should be 7 / Sollte 7 sein
# Multiplication / Multiplikation
prod_ab <- a ____ b
print(prod_ab) # Should be 30 / Sollte 30 sein
# Division
div_ab <- a ____ b
print(div_ab) # Should be 3.333... / Sollte 3.333... sein
# Power (10 to the power of 3) / Potenz (10 hoch 3)
power_ab <- a ____ b
print(power_ab) # Should be 1000 / Sollte 1000 sein
# Variables can change!
# Variablen können sich ändern!
# Start with a count of species
# Starte mit einer Artenanzahl
species_count <- 0
print(species_count)
# Found 5 species / 5 Arten gefunden
species_count <- species_count + ____
print(species_count) # Should be 5 / Sollte 5 sein
# Found 3 more / 3 weitere gefunden
species_count <- species_count + ____
print(species_count) # Should be 8 / Sollte 8 sein
# Oops, 2 were misidentified (subtract)
# Ups, 2 waren falsch bestimmt (subtrahieren)
species_count <- species_count - ____
print(species_count) # Should be 6 / Sollte 6 sein
Hint: Math operators are +
- * / and ^ for
power. Use == for “equals” comparison! Hinweis: Rechenoperatoren sind + -
* / und ^ für Potenz. Benutze
== für “gleich” Vergleich!
Concept: A vector is a list of
values of the same type. We use c() to combine values into
a vector.
Konzept: Ein Vektor ist eine Liste
von Werten des gleichen Typs. Wir benutzen c() um Werte zu
kombinieren.
# Create a vector of numbers
# Erstelle einen Vektor von Zahlen
species_counts <- c(5, 3, 7, 2, 4)
print(species_counts)
# Your turn - create a vector of 4 tree heights
# Du bist dran - erstelle einen Vektor mit 4 Baumhöhen
tree_heights <- c(____, ____, ____, ____)
print(tree_heights)
# Create a vector of species names
# Erstelle einen Vektor von Artnamen
tree_species <- c("Oak", "Beech", "Pine", "Maple")
print(tree_species)
# How many elements in the vector?
# Wie viele Elemente im Vektor?
length(species_counts)
# Calculate the sum
# Berechne die Summe
sum(species_counts)
# Calculate the mean (average)
# Berechne den Mittelwert (Durchschnitt)
mean(species_counts)
# Your turn - calculate mean of your tree heights
# Du bist dran - berechne den Mittelwert deiner Baumhöhen
mean(____)
# Find min and max
# Finde Minimum und Maximum
min(species_counts)
max(species_counts)
# Species from different plots
# Arten von verschiedenen Plots
plot1 <- c("Oak", "Beech", "Pine")
plot2 <- c("Beech", "Maple", "Oak")
plot3 <- c("Birch", "Oak", "Ash")
# Combine all into one vector
# Kombiniere alle in einen Vektor
all_species <- c(plot1, plot2, plot3)
print(all_species)
# How many total observations?
# Wie viele Beobachtungen insgesamt?
length(all_species)
Hint: c() combines values.
length() counts elements. mean() calculates
average. Hinweis: c() kombiniert
Werte. length() zählt Elemente. mean()
berechnet Durchschnitt.
Concept: unique() is the key
function for ecology! It tells us how many different
species we found (not counting duplicates).
Konzept: unique() ist die
Schlüsselfunktion für Ökologie! Sie sagt uns, wie viele
verschiedene Arten wir gefunden haben (ohne Duplikate).
# 3a: We observed these species (some repeats!)
# 3a: Wir haben diese Arten beobachtet (einige Wiederholungen!)
observations <- c("Oak", "Beech", "Oak", "Pine", "Beech", "Oak", "Maple")
# How many observations total?
# Wie viele Beobachtungen insgesamt?
length(observations)
# 3b: How many UNIQUE species?
# 3b: Wie viele EINZIGARTIGE Arten?
unique(observations)
length(unique(observations))
# 3c: Using our plots from before
# 3c: Benutze unsere Plots von vorher
plot1 <- c("Oak", "Beech", "Pine")
plot2 <- c("Beech", "Maple", "Oak")
plot3 <- c("Birch", "Oak", "Ash")
all_species <- c(plot1, plot2, plot3)
# Total observations vs unique species
# Gesamte Beobachtungen vs einzigartige Arten
length(all_species) # Total / Gesamt
length(unique(all_species)) # Unique / Einzigartig
# 3d: Your turn - how many unique species after plot1 + plot2?
# 3d: Du bist dran - wie viele einzigartige Arten nach plot1 + plot2?
after_two_plots <- c(plot1, ____)
length(unique(after_two_plots))
Hint: Species richness =
length(unique(species_list)). This is THE key
formula! Hinweis: Artenreichtum =
length(unique(artenliste)). Das ist DIE
Schlüsselformel!
A data frame is like a spreadsheet - it has rows and columns. Let’s practice with a small example before loading real data!
Ein Data Frame ist wie eine Tabelle - er hat Zeilen und Spalten. Üben wir mit einem kleinen Beispiel, bevor wir echte Daten laden!
# 4a: Create a simple data frame
# 4a: Erstelle einen einfachen Data Frame
my_data <- data.frame(
species = c("Oak", "Beech", "Pine", "Maple"),
height = c(20, 18, 25, 15),
native = c(TRUE, TRUE, TRUE, FALSE)
)
my_data
# 4b: How many rows and columns?
# 4b: Wie viele Zeilen und Spalten?
nrow(my_data)
ncol(my_data)
# 4c: Access a column with $
# 4c: Greife auf eine Spalte mit $ zu
my_data$species
my_data$height
# 4d: Your turn - get the mean height
# 4d: Du bist dran - berechne die mittlere Höhe
mean(my_data$___)
# 4e: Access a specific row (row 2)
# 4e: Greife auf eine bestimmte Zeile zu (Zeile 2)
my_data[2, ]
# 4f: Access a specific cell (row 2, column "height")
# 4f: Greife auf eine bestimmte Zelle zu (Zeile 2, Spalte "height")
my_data[2, "height"]
Hint: $ accesses columns by name.
Square brackets [row, column] access specific cells.
Hinweis: $ greift auf Spalten per Name zu.
Eckige Klammern [zeile, spalte] greifen auf bestimmte
Zellen zu.
Now let’s load the Austrian vegetation data!
Jetzt laden wir die österreichischen Vegetationsdaten!
# 5a: Load the tidyverse package
# 5a: Lade das tidyverse Paket
library(tidyverse)
# 5b: Load the species data
# 5b: Lade die Artdaten
species_data <- read_csv("../data/austria_species.csv")
# 5c: Look at the first few rows
# 5c: Schau dir die ersten Zeilen an
head(species_data)
# 5d: How many rows (observations)?
# 5d: Wie viele Zeilen (Beobachtungen)?
nrow(species_data)
# 5e: What columns do we have?
# 5e: Welche Spalten haben wir?
colnames(species_data)
# 5f: How many unique plots?
# 5f: Wie viele einzigartige Plots?
length(unique(species_data$PlotObservationID))
# 5g: How many unique species in the whole dataset?
# 5g: Wie viele einzigartige Arten im gesamten Datensatz?
length(unique(species_data$___))
Hint: Use $ to access a column,
e.g. data$column_name Hinweis:
Benutze $ um auf eine Spalte zuzugreifen, z.B.
data$spaltenname
Often we want to look at only part of our data. The
filter() function helps us select specific rows!
Oft wollen wir nur einen Teil unserer Daten
betrachten. Die filter() Funktion hilft uns, bestimmte
Zeilen auszuwählen!
# 6a: Look at the STATUS column - what values are there?
# 6a: Schau dir die STATUS-Spalte an - welche Werte gibt es?
unique(species_data$STATUS)
# 6b: Filter for native species only (STATUS == "nat")
# 6b: Filtere nur heimische Arten (STATUS == "nat")
native_only <- species_data %>%
filter(STATUS == "nat")
nrow(native_only)
# 6c: Filter for alien/invasive species (STATUS == "neo")
# 6c: Filtere Alien/invasive Arten (STATUS == "neo")
alien_only <- species_data %>%
filter(STATUS == "neo")
nrow(alien_only)
# 6d: How many unique native species?
# 6d: Wie viele einzigartige heimische Arten?
length(unique(native_only$WFO_TAXON))
# 6e: Your turn - how many unique alien species?
# 6e: Du bist dran - wie viele einzigartige Alien-Arten?
length(unique(___$WFO_TAXON))
# 6f: Filter for a specific plot
# 6f: Filtere einen bestimmten Plot
first_plot <- unique(species_data$PlotObservationID)[1]
first_plot
one_plot <- species_data %>%
filter(PlotObservationID == first_plot)
# How many species in this one plot?
# Wie viele Arten in diesem einen Plot?
length(unique(one_plot$WFO_TAXON))
Hint: filter() keeps rows where the
condition is TRUE. Use == for “equals”. Hinweis: filter() behält Zeilen, wo die
Bedingung TRUE ist. Benutze == für “gleich”.
Now the exciting part - let’s build a species accumulation curve step by step!
Jetzt der spannende Teil - bauen wir eine Artenakkumulationskurve Schritt für Schritt!
# 7a: Get a list of all unique plots
# 7a: Hole eine Liste aller einzigartigen Plots
all_plots <- unique(species_data$PlotObservationID)
head(all_plots)
# 7b: Take a small sample (first 50 plots for speed)
# 7b: Nimm eine kleine Stichprobe (erste 50 Plots für Geschwindigkeit)
sample_plots <- all_plots[1:50]
# 7c: Initialize our accumulation tracking
# 7c: Initialisiere unsere Akkumulations-Verfolgung
species_found <- c() # Empty vector to collect species
# Leerer Vektor um Arten zu sammeln
accumulation <- c() # Will store species count after each plot
# Speichert Artenzahl nach jedem Plot
# 7d: Loop through each plot and count species!
# 7d: Schleife durch jeden Plot und zähle Arten!
for (i in 1:length(sample_plots)) {
# Get current plot ID
# Hole aktuelle Plot-ID
current_plot <- sample_plots[i]
# Get species in this plot
# Hole Arten in diesem Plot
plot_species <- species_data$WFO_TAXON[species_data$PlotObservationID == current_plot]
# Add to our collection
# Füge zu unserer Sammlung hinzu
species_found <- c(species_found, plot_species)
# Count unique species so far
# Zähle einzigartige Arten bisher
total_species <- length(unique(species_found))
# Store in accumulation vector
# Speichere im Akkumulationsvektor
accumulation <- c(accumulation, total_species)
}
# 7e: Look at the result!
# 7e: Schau dir das Ergebnis an!
accumulation
The final step - let’s visualize our accumulation curve!
Der letzte Schritt - visualisieren wir unsere Akkumulationskurve!
# 8a: Create a data frame for plotting
# 8a: Erstelle einen Data Frame zum Plotten
curve_data <- data.frame(
plots = 1:length(accumulation),
species = accumulation
)
head(curve_data)
# 8b: Make the plot!
# 8b: Mache den Plot!
ggplot(curve_data, aes(x = plots, y = species)) +
geom_line(color = "#2E7D32", linewidth = 2) +
geom_point(color = "#2E7D32", size = 2) +
labs(
title = "My First Species Accumulation Curve!",
x = "Number of Plots Sampled",
y = "Cumulative Species Count"
) +
theme_minimal(base_size = 14)
# 8c: Make it prettier with a filled area
# 8c: Mache es schöner mit gefüllter Fläche
ggplot(curve_data, aes(x = plots, y = species)) +
geom_area(fill = "#C8E6C9", alpha = 0.5) +
geom_line(color = "#2E7D32", linewidth = 2) +
labs(
title = "Species Accumulation Curve - Austria",
subtitle = paste("Total species found:", max(accumulation)),
x = "Plots Sampled",
y = "Cumulative Species"
) +
theme_minimal(base_size = 14)
Hint: The curve flattens because we find fewer NEW species as we sample more plots! Hinweis: Die Kurve flacht ab, weil wir weniger NEUE Arten finden, je mehr Plots wir untersuchen!
If you finish early, try comparing native and alien species!
Wenn du früh fertig bist, versuche heimische und Alien-Arten zu vergleichen!
# The species_data already has a STATUS column!
# Die species_data hat bereits eine STATUS-Spalte!
# Filter for native species only
# Filtere nur heimische Arten
native_species <- species_data %>%
filter(STATUS == "nat")
# How many native species?
# Wie viele heimische Arten?
length(unique(native_species$WFO_TAXON))
# How many alien species?
# Wie viele Alien-Arten?
alien_species <- species_data %>%
filter(STATUS == "neo")
length(unique(alien_species$WFO_TAXON))
# Now you can build separate curves for native vs alien!
# Jetzt kannst du separate Kurven für heimisch vs alien bauen!
You did it! You built your first species accumulation curve using real Austrian data!
Key concepts learned: - Variables store data with
<- - c() creates vectors -
unique() counts different values - Data frames organize
data in rows and columns - filter() selects specific rows -
Loops let us repeat actions - ggplot() creates beautiful
plots
Du hast es geschafft! Du hast deine erste Artenakkumulationskurve mit echten österreichischen Daten gebaut!
Gelernte Schlüsselkonzepte: - Variablen speichern
Daten mit <- - c() erstellt Vektoren -
unique() zählt verschiedene Werte - Data Frames
organisieren Daten in Zeilen und Spalten - filter() wählt
bestimmte Zeilen aus - Schleifen lassen uns Aktionen wiederholen -
ggplot() erstellt schöne Plots