library("readr")
library("lubridate")
wetter <- read_delim("datasets/prepro/weather_prepro4.csv", ",")
wetter$time <- as.POSIXct(as.character(wetter$time), format = "%Y%m%d%H", tz = "UTC")
wetter$monat <- month(wetter$time)Prepro 4: Debugging
Demo
Was ist Debugging?
Bevor wir näher darauf eingehen, was Debugging ist, müssen wir zuerst erklären, was ein Bug ist.
Was also ist ein Bug beim Programmieren?
Darunter versteht man einen Fehler in einem Computercode, Syntaxfehler, Laufzeitfehler und logische Fehler.
Wer mehr wissen möchte, wie ein Insekt sich in die Computersprache eingeschlichen hat, kann sich hier informieren:
Welche Fehler kann es geben?
- “Gute” Fehler: Der Code läuft nicht. R gibt eine Fehlermeldung aus und zwingt uns, den Fehler zu erkennen → Der Fehler macht sich bemerkbar.
- “Schlechte” Fehler: Der Code läuft ohne Fehlermeldung, liefert aber ein falsches oder unerwartetes Ergebnis → Wir müssen den Fehler selbst erkennen.
- Die gefährlichsten Fehler: Der Code läuft und liefert ein plausibel aussehendes falsches Ergebnis → Ohne fachliches und methodisches Verständnis bleibt der Fehler möglicherweise unentdeckt.
Die letzten beide Punkte zeigen, dass ein funktionierender Code nicht zwingend auch ein korrekter Code ist.
Was ist jetzt Debugging? Damit meint man das Entfernen von Code-Fehlern.
Debugging in R/RStudio
Aber wie werden Bugs entfernt? Dafür gibt es eine ganze Reihe von verschiedenen Methoden. In diesem Block zeigen wir, welche Methoden in R/RStudio für diesen Kurs hilfreich sind.
Wir werden diese anhand von Beispielen in dieser Demo durchgehen.
Zuerst laden wir den Datensatz ein und kreieren die Convenience Variable monat.
Beispiel 1: Base R
mean(wetter$tre200h0[wetter$monat == "Januar"])
mean(wetter$tre200h0[wetter$monat == "Februar])
mean(wetter$tre200h0[wetter$monat == "März"])Bevor der Code ausgeführt wird, machen wir uns einige Gedanken:
Was wird in RStudio angezeigt? → Rote Kreuze erscheinen, einen Teil ist grün eingefärbt.
Was könnte dazu führen? → Vermutung: nicht geschlossene Klammern, Strings.
Wo liegt vermutlich der Fehler? → Kreuze erscheinen immer in dieser Zeile, wo der Fehler beginnt
Wie löse ich diesen Fehler? → Bei
"FebruarString schliessen
Jetzt lassen wir den Code laufen.
mean(wetter$tre200h0[wetter$monat == "Januar"])
mean(wetter$tre200h0[wetter$monat == "Februar"])
mean(wetter$tre200h0[wetter$monat == "März"])Was ist der Output dieses Codes? → NaN als Ergebnis
Wo liegt vermutlich der Fehler? → noch nicht eindeutig, vieles könnte dazu führen.
Wie löse ich diesen Fehler? → einzelne Codeteile analysieren, damit Problem im Code lokalisiert werden kann
Welche Werte sind in der Spalte monat enthalten?
wetter$monat[1:10]
## [1] 1 1 1 1 1 1 1 1 1 1Das Problem ist, dass monat als Integer codiert ist und nicht mit Namen. Wir haben somit unseren Fehler lokalisiert und können ihn debuggen.
wetter$monat == 1
wetter$monat == 2
wetter$monat == 3Jetzt lassen wir den Code noch einmal laufen, damit wir den Output begutachten können.
mean(wetter$tre200h0[wetter$monat == 1])
## [1] -1.963239
mean(wetter$tre200h0[wetter$monat == 2])
## [1] 0.3552632
mean(wetter$tre200h0[wetter$monat == 3])
## [1] 2.965054Jetzt sieht der Output gut sein.
Beispiel 2: Piping
Wir verwenden den gleichen Datensatz von oben und wollen die monatliche Durchschnittstemperatur berechnen.
library(dplyr)
wetter_summary <- wetter |>
group_by(monate) |>
summarise(
temp_mean = mean(tre200h0)
)
## Error in `group_by()`:
## ! Must group by variables found in `.data`.
## ✖ Column `monate` is not found.Was ist der Output dieses Codes? → Es erscheint die Fehlermeldung: Error in
group_by(): ! Must group by variables found in.data. ✖ Columnmonateis not found.Wo liegt das Problem? → Die Spalte
monateist nicht im Datensatz enthalten.Wie löse ich dieses Problem? → Autocomplete von RStudio verwenden und/oder Überprüfung der Spaltennamen, damit der richtige Spaltenname verwendet werden kann.
colnames(wetter)
## [1] "stn" "time" "tre200h0" "monat"Wir bereinigen den Code und lassen den gefixten Code laufen:
wetter_summary <- wetter |>
group_by(monat) |>
summarise(
temp_mean = mean(tre200h0)
)Was ist der Output dieses Codes? → Der Code läuft ohne Fehlermeldung durch, dafür ist der Output nicht zufriedenstellend, da im Monat April NA als Durchschnittstemperatur erscheint.
Wo liegt vermutlich das Problem? → Werte im April
Wie löse ich diesen Fehler? → Temperaturwerte im April anschauen
wetter |>
filter(monat == 4 & is.na(tre200h0))Wie es scheint, fiel an einem Tag im April 2000 der Sensor aus.
- Wie löse ich dieses Problem? →
mean(tre200h0, na.rm = T)definieren
wetter_summary <- wetter |>
group_by(monat) |>
summarise(
temp_mean = mean(tre200h0, na.rm = T)
)Zusammenfassung
Welche Methoden sind nun in RStudio/R hilfreich?
- Error-Messages lesen und versuchen, zu entschlüsseln.
- Hilfe nutzen, z.B. rotes Kreuz bei nicht geschlossenen Klammern, grüne Einfärbung von Text bei nicht geschlossenen Strings
- nur Teile eines Codes ausführen
Wie kann nun KI helfen?
Um nicht jedes Mal den ganzen Code einer KI zu geben, ist es wichtig, den Bug im eigenen Code lokalisieren zu können, d.h. wo stoppt der Code oder wo ist der Output nicht zufriedenstellend. Nach Lokalisation des Bugs kann KI uns helfen, den Bug zu fixen, indem wir den fehlerhafte Code, evtl. den Output und, wenn vorhanden, die Fehlermeldung prompten, z.B. so:
«Aus einer as.Posix-Spalte
timehabe ich vorhängig die Spaltemonatmitmonth(wetter$time)konstruiert.mean(wetter$tre200h0[wetter$monat == "Januar"])liefert nunNA.»
Eine mögliche Antwort wäre:
«Wenn du
monatmitwetter$monat <- month(wetter$time)erzeugt hast (aus dem Paket lubridate), dann liefertmonth()standardmässig die Zahlen 1–12. Dann gibt es gar keine Werte “Januar”.»
Unser Lösungsvorschlag zum Debuggen:
- Fehler lokalisieren und versuchen, diesen selber zu beheben
- KI um Erklärung/Hinweis bitten
- Lösung testen und Output kontrollieren!
- Lösung verstehen, denn es gilt: aus Fehlern lernt man
Übungen
Lade die folgenden Libraries:
library("readr")
library("lubridate")
library("dplyr")Aufgabe 1
Führe diesen Code aus und schau dir den Output an:
wetter <- read.csv("datasets/prepro/weather_prepro4.csv")
wetter_prec <- read.csv("datasets/prepro/weather_prepro4_precipitation.csv")Welcher Output sieht falsch aus und warum? Welchen Output hättest du erwartet? Lokalisiere das Problem. Frage danach eine KI deiner Wahl nach zwei verschiedene Lösungen.
Gibt die KI dieselben Funktionen aus wie du sie bereits im Unterricht gesehen hast?
Fixe den Bug mit dem Code deiner Wahl, lasse den Code noch einmal laufen und kontrolliere den Output.
Prompt: Ich möchte ein csv file in RStudio mit read.csv hineinladen, jedoch werden die Spalten nicht erkannt. Kannst du mir zwei Lösungsvorschläge machen?
wetter <- read_delim("datasets/prepro/weather_prepro4.csv")
wetter_prec <- read_delim("datasets/prepro/weather_prepro4_precipitation.csv", delim = ";")Aufgabe 2
Verwende die Datensätze von Aufgabe 1, welche nun richtig eingelesen sein sollten. Führe folgenden Code aus:
wetter |>
mutate(jahr = year(time))Erkennst du den Fehler direkt anhand des Wissens, welches du dir in den vorhergehenden Übungen erlernt hast? Kannst du den Fehler lokalisieren? Formuliere ansonsten einen Prompt und lokalisiere so den Bug.
Prompt:
Ich versuche, in einem Datensatz eine neue Spalte ‘jahr’ aus der bereits vorhandenen Spalte ‘time’ (erste Zeile z.B. 2000010100) zu berechnen. Mein Code lautet wetter |> mutate(jahr = year(time)). Es erscheint jedoch die Fehlermeldung:
Warnung: There was 1 warning in mutate(). ℹ In argument: jahr = year(time). Caused by warning: ! tz(): Don’t know how to compute timezone for object of class numeric; returning “UTC”.
Wie muss der Code angepasst werden?
Lösung: year() aus lubridate erwartet, dass die Eingabe ein Datum/Zeit-Objekt ist. Daher muss die Spalte time zuerst umgewandelt werden.
Aufgabe 3
Welche Error-Meldung erscheint zuerst beim Ausführen dieses Codes? Versuche sie zu verstehen, löse den Fehler direkt und/oder frage eine KI deiner Wahl nach Debugging-Strategien.
weather |>
mutate(time = as.POSIXct(as.character(time), format = "%Y%m%d", tz = "UTC"),
jahr = year(time)
)Zuerst erscheint die Fehlermeldung Fehler: Objekt 'weather' nicht gefunden. Die Variable müsste jedoch wetter heissen.
Stimmt die Format-Schablone für as.POSIXct()? Schau dir den Output an. Frage wenn nötig eine KI um eine passende Schablone. Gibt dazu ein Wert-Beispiel aus der Spalte time mit. Passe den Code an und überprüfe den Output.
Prompt: Ein Wert aus der Spalte time sieht so aus: 2000010100. Kannst du mir die passende Formatschablone für as.POSIXct geben?
wetter |>
mutate(time = as.POSIXct(as.character(time), format = "%Y%m%d%H", tz = "UTC"),
jahr = year(time)
)Aufgabe 4
Nun sollst du mit untenstehendem die Minimaltemperatur in Grad Celsius und in Grad Fahrenheit pro Jahr berechnen. Läuft der Code bei dir durch? Wenn nein, lokalisiere das Problem, indem du den Code teilweise laufen lässt. Frage wenn nötig eine KI, was das Problem sein könnte. Tipp: Geb der KI auch den Code aus Aufgabe 3.
wetter_max <- wetter |>
group_by(jahr) |>
summarise(min_temp = min(tre200h0, na.rm = T)) |>
mutate(min_temp_F = 5/9 * min_temp + 32)Prompt:
Ich habe in meinem R Code hier das Problem: wetter |> group_by(jahr)
Error in group_by(): ! Must group by variables found in .data. ✖ Column jahr is not found. Run rlang::last_trace() to see where the error occurred.
Etwas vorher mache ich das:
wetter |> mutate(time = as.POSIXct(as.character(time), format = “%Y%m%d%H”, tz = “UTC”), jahr = year(time) )
Lösung:
Beim Kreieren der Convenience Variable ‘jahr’ wurde das Ganze nicht als Variable abgespeichert und somit steht die Spalte nicht zur Verfügung.
wetter <- wetter |>
mutate(time = as.POSIXct(as.character(time), format = "%Y%m%d%H", tz = "UTC"),
jahr = year(time)
)Schau dir wetter_max genau an und überlege dir, ob die Werte in min_temp und min_temp_F stimmen können. Frage zur Sicherheit eine KI, indem du den Code in einen Prompt verpackst.
Prompt:
Ich bin mir nicht sicher, ob dieser Code stimmt:
wetter |> group_by(jahr) |> summarise(min_temp = min(tre200h0, na.rm = T)) |> mutate(min_temp_F = 5/9 * min_temp + 32)
Es handelt sich hier um einen gefährlichen Fehler! Die Werte in Grad Fahrenheit scheinen plausibel, jedoch ist die Formel falsch.
wetter_max <- wetter |>
group_by(jahr) |>
summarise(min_temp = min(tre200h0, na.rm = T)) |>
mutate(min_temp_F = 9/5 * min_temp + 32)Aufgabe 5
Die beiden Datensätze wetter und wetter_max sollen nun über einen geeigneten Join miteinader verbunden werden. Der Code läuft jedoch nicht durch. Löse den folgenden Bug, entweder selbständig oder mit Anwendung von KI. Lasse dir, falls nötig, einen Code für die Lösung des Bugs von der KI generieren.
left_join(wetter_max, wetter_prec, by = "jahr")Jeweils anderer Datentyp in den Spalten ‘jahr’, character bzw. double.
Lösung:
In wetter_prec muss die Spalte von character in double bzw. integer umgewandelt werden.
wetter_prec <- wetter_prec |>
mutate(jahr = as.integer(gsub("'", "", jahr)))
left_join(wetter_max, wetter_prec, by = "jahr")