Help me help you: Wie man ein R-Problem so formuliert, dass einem geholfen werden kann

Hier werden Sie geholfen – oder doch nicht?

Die Hausarbeit zur Datenanalyse mit R muss morgen Abend abgegeben werden – und nichts läuft! Wer kennt das nicht?! Der knurrige Dozent hat die Abgabefrist wieder viel zu knapp bemessen, warum auch immer. Was ist jetzt zu tun? Nach 3 13 30 60 Minuten eigenen – erfolglosen – Tüftelns will man jetzt den Dozenten um Hilfe fragen.

Man schreibt also: “Lieber Herr Süß, R läuft nicht, was soll ich tun?”. Seltsamerweise reagiert der Dozent nicht wahnsinnig hilfsbereit. Er murmelt etwas von genaueren Infos, die er benötige. Also schicken Sie einen Screenshot hinterher, der eine Fehlermeldung zeigt. Jetzt beschwert er sich (schon wieder), dass er aus dem Screenshot abtippen müsste. Also gut, dann schicken Sie halt noch eine Mail mit der betreffenden Zeile R-Syntax. Allerdings: Wieder rückfragen: Welche Pakete Sie geladen hätten? Das haben Sie noch gar nicht gesagt (welche Pakete waren eigentlich geladen bzw. nicht geladen? Ohje, das könnte dann doch der Fehler sein …). Schon wieder eine Mail hin und her. Kurz fragen Sie sich, wenn das alle 300 Studierende so machen, ob das den Dozenten nicht ganz schön auf Trab hält?

Gängige Erste-Hilfe-Maßnahmen

OK, die folgenden Ideen sind nicht gerade tiefschürfend, aber tatsächlich helfen Sie oft. Und sie sind mit sehr wenig Aufwand für Sie zu erledigen:

  • Rechner neustarten
  • R aktualisieren
  • RStudio aktualisieren
  • Betriebssystem aktualisieren
  • R-Pakete aktualisieren (update.packages() oder Klick auf den entsprechenden Menüpunkt)
  • RStudio als Admin starten und dann nochmal die Pakte installieren/updaten
  • Virenscanner ausschalten und dann nochmal die Pakte installieren/updaten

Und natürlich: Recherchieren, vor allem auf Stackoverflow.

Eine Bitte zu Beginn: Erst selber probieren

Nennen wir es die 30-Minuten-Schlaf-drüber-10-Webseiten-Regel. Bevor Sie jemanden um Hilfe bitten, sollten Sie sich ernsthaft selber bemüht haben:

  1. Sie haben mindestens 30 Minuten ernsthaft über das Problem nachgedacht.
  2. Sie haben eine Nacht drüber geschlafen. (Es ist erstaunlich, wie viele Probleme sich mit etwas Abstand auf einmal scheinbar von alleine lösen.)
  3. Sie haben auf mindestens 10 Webseiten recherchiert, wie man das Problem lösen könnte.

Notausgang RStudio Cloud

Wenn RStudio auf Ihrem Rechner nicht läuft, können Sie als Ausweichlösung mit RStudio Cloud arbeiten. Dort sind einige Pakete (z.B. tidyverse; aber auch \(TeX\)) bereits installiert; Sie können auch selber Pakete installieren. Häufig lassen sich technische Probleme (wenn Sie in der Software-Installation zu suchen sind) umgehen.

ERBie

Mal kurz aus Dozentensicht: Die Geschichte oben ist nicht sonderlich befriedigend. Wenn Sie jemanden um Hilfe bitten, dann sollten Sie dieser Person nicht unnötig Arbeit aufbürden. Im Klartext: Sie müssen alle Informationen bereitstellen, die der “R-Doktor” für seine Diagnose braucht. Außerdem sollten Sie alle unnötigen Informationen weglassen – also keinen R-Code übermitteln, der für das Problem ohne Relevanz ist.

Kurz gesagt: Schicken Sie dem Dozenten ein MINIMALES, LAUFFÄHIGES, R- oder RMD-Skript.

Das fürht zu diesen Kriterien:

  1. Hintergrund: Was will ich erreichen, was habe ich versucht?

  2. Minimaler Datensatz, so klein wie möglich

  3. Minimaler R-Code, der nötig ist, dass Problem zu demonstrieren.

  4. Hinweise zu geladenen Paketen und weiteren technischen Spezifikationen.

In meinem R-Buch nenne ich solche R-Syntax-Beispiele Erbies, für Einfache, reproduzierbare (nachprüfbare) Beispiele. Lesen Sie dort (Kap. 3.8) zu weiteren Details nach.

Schauen wir uns das etwas im Detail an:

Kriterium 1: Hintergrund: Was will ich erreichen, was habe ich versucht?

Stellen Sie zu Beginn Ihrer Anfrage – kurz aber präzise – dar,

  • was Sie erreichen wollen
  • was das Problem ist
  • was Sie bisher versucht haben, das Problem zu lösen. Dazu gehört auch, dass Sie Quellen zitieren (als Link reicht), die Sie konsultiert haben. Beschreiben Sie kurz den Lösungsansatz in der Quelle, und was das Ergebnis bei Ihnen war.

Kriteriumm 2: Minimaler Datensatz, so klein wie möglich

Ein einfache Möglichkeit für minimale Datensätze ist es, “einbaute” Datensätze zu verwenden, etwa mtcars:

data(mtcars)
str(mtcars)
#> 'data.frame':    32 obs. of  11 variables:
#>  $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
#>  $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
#>  $ disp: num  160 160 108 258 360 ...
#>  $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
#>  $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
#>  $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
#>  $ qsec: num  16.5 17 18.6 19.4 17 ...
#>  $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
#>  $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
#>  $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
#>  $ carb: num  4 4 1 1 2 1 4 2 2 4 ...

Alternativ könnten Sie auch den Datensatz tips nutzen. Komfortabel ist, dass Sie ihn so herunterladen können:

tips <- read.csv("https://data-se.netlify.app/download/tips.csv")

Alternativ finden Sie den Datensatz tips auch in R-Paket reshape2:

library(datasets)

Kriterium 3: Minimaler R-Code, der nötig ist, dass Problem zu demonstrieren.

Übermitteln Sie nur den nötigen R-Code für Ihr Problem: Lassen Sie keinen benötigten R-Code weg, aber fügen Sie nicht unnötigen (für Ihr Problem unnötigen!) R-Code hinzu.

Vergessen Sie nicht, die nötigen Pakete vorab zu laden, etwa so:

library(mosaic)
library(tidyverse)

Kriterium 4: Hinweise zu geladenen Paketen und weiteren technischen Spezifikationen.

Dieses Kriterium ist einfach erledigt, wenn Sie zum Schluss in Ihrer Syntax den Befehl sessionInfo() anfügen:

sessionInfo()
#> R version 4.0.2 (2020-06-22)
#> Platform: x86_64-apple-darwin17.0 (64-bit)
#> Running under: macOS Catalina 10.15.6
#> 
#> Matrix products: default
#> BLAS:   /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRblas.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib
#> 
#> locale:
#> [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#>  [1] mosaic_1.7.0      Matrix_1.2-18     mosaicData_0.18.0 ggformula_0.9.4  
#>  [5] ggstance_0.3.4    lattice_0.20-41   forcats_0.5.0     stringr_1.4.0    
#>  [9] dplyr_1.0.2       purrr_0.3.4       readr_1.3.1       tidyr_1.1.2      
#> [13] tibble_3.0.3      ggplot2_3.3.2     tidyverse_1.3.0  
#> 
#> loaded via a namespace (and not attached):
#>  [1] ggdendro_0.1.21   httr_1.4.2        jsonlite_1.7.0    splines_4.0.2    
#>  [5] modelr_0.1.8      assertthat_0.2.1  blob_1.2.1        cellranger_1.1.0 
#>  [9] yaml_2.2.1        ggrepel_0.8.2     pillar_1.4.6      backports_1.1.9  
#> [13] glue_1.4.2        digest_0.6.25     polyclip_1.10-0   rvest_0.3.6      
#> [17] colorspace_1.4-1  htmltools_0.5.0   pkgconfig_2.0.3   broom_0.7.0      
#> [21] haven_2.3.1       bookdown_0.20     scales_1.1.1      tweenr_1.0.1     
#> [25] ggforce_0.3.2     generics_0.0.2    farver_2.0.3      ellipsis_0.3.1   
#> [29] withr_2.2.0       lazyeval_0.2.2    cli_2.0.2         magrittr_1.5     
#> [33] crayon_1.3.4      readxl_1.3.1      evaluate_0.14     fs_1.5.0         
#> [37] fansi_0.4.1       MASS_7.3-52       xml2_1.3.2        blogdown_0.20    
#> [41] tools_4.0.2       hms_0.5.3         lifecycle_0.2.0   munsell_0.5.0    
#> [45] reprex_0.3.0      compiler_4.0.2    rlang_0.4.7       grid_4.0.2       
#> [49] rstudioapi_0.11   htmlwidgets_1.5.1 crosstalk_1.1.0.1 mosaicCore_0.6.0 
#> [53] rmarkdown_2.3     gtable_0.3.0      codetools_0.2-16  DBI_1.1.0        
#> [57] R6_2.4.1          gridExtra_2.3     lubridate_1.7.9   knitr_1.29       
#> [61] stringi_1.4.6     Rcpp_1.0.5        vctrs_0.3.4       leaflet_2.0.3    
#> [65] dbplyr_1.4.4      tidyselect_1.1.0  xfun_0.16

Tipp: Wie man trotz Fehler ein Rmd-Skript zum Laufen kriegt

Wenn Sie einen Fehler im Skript haben, können Sie auf einfache Weise R dazu bringen, das Rmd-Skript trotzdem durchlaufen zu lassen. Voraussetzung ist natürlich, dass der Fehler nicht an späterer Stelle noch alles mögliche kaputt macht, so dass das Durchlaufen gar keinen Sinn machen würde.

Das Zauberwort heißt error = TRUE; diesen Zusatz fügen Sie in den R-Chunk ein, der Ihnen ein Problem macht. Und zwar in die “Kopfzeile”, in die geschweifte Klammer. Sagen wir, Sie haben diesen nervigen R-Chunk mit Fehler, der dazu führt, dass Ihr Code nicht durchläuft:

favstats(  hp, data = mtcars)  # wo ist hier der Fehler?!?
#> Error in rlang::is_formula(x): object 'hp' not found

Nur der HeRRR-Gott weiß, was hier schon wieder nicht passt ?!

Nehmen Sie also diesen R-Chunk:


#```{r}
#favstats(  hp, data = mtcars)
#```

Und ergänzen Sie in der geschweiften Klammer den Parameter error=TRUE:


#```{r error = TRUE}
#favstats(  hp, data = mtcars)
#```

Dann wird R einfach eine Fehlermeldung drucken, aber danach brav weiter gehen, um die nächste R-Stelle auszuführen.

Beispiel für ein ERBIE

data(mtcars)

d_kurz <- select(mtcars, hp, am)

favstats(hp ~ am, dataset = d_kurz)  # hier kommt der Fehler!
#> Error in eval(x, data, env): object 'hp' not found

sessionInfo()
#> R version 4.0.2 (2020-06-22)
#> Platform: x86_64-apple-darwin17.0 (64-bit)
#> Running under: macOS Catalina 10.15.6
#> 
#> Matrix products: default
#> BLAS:   /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRblas.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib
#> 
#> locale:
#> [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#>  [1] mosaic_1.7.0      Matrix_1.2-18     mosaicData_0.18.0 ggformula_0.9.4  
#>  [5] ggstance_0.3.4    lattice_0.20-41   forcats_0.5.0     stringr_1.4.0    
#>  [9] dplyr_1.0.2       purrr_0.3.4       readr_1.3.1       tidyr_1.1.2      
#> [13] tibble_3.0.3      ggplot2_3.3.2     tidyverse_1.3.0  
#> 
#> loaded via a namespace (and not attached):
#>  [1] ggdendro_0.1.21   httr_1.4.2        jsonlite_1.7.0    splines_4.0.2    
#>  [5] modelr_0.1.8      assertthat_0.2.1  blob_1.2.1        cellranger_1.1.0 
#>  [9] yaml_2.2.1        ggrepel_0.8.2     pillar_1.4.6      backports_1.1.9  
#> [13] glue_1.4.2        digest_0.6.25     polyclip_1.10-0   rvest_0.3.6      
#> [17] colorspace_1.4-1  htmltools_0.5.0   pkgconfig_2.0.3   broom_0.7.0      
#> [21] haven_2.3.1       bookdown_0.20     scales_1.1.1      tweenr_1.0.1     
#> [25] ggforce_0.3.2     generics_0.0.2    farver_2.0.3      ellipsis_0.3.1   
#> [29] withr_2.2.0       lazyeval_0.2.2    cli_2.0.2         magrittr_1.5     
#> [33] crayon_1.3.4      readxl_1.3.1      evaluate_0.14     fs_1.5.0         
#> [37] fansi_0.4.1       MASS_7.3-52       xml2_1.3.2        blogdown_0.20    
#> [41] tools_4.0.2       hms_0.5.3         lifecycle_0.2.0   munsell_0.5.0    
#> [45] reprex_0.3.0      compiler_4.0.2    rlang_0.4.7       grid_4.0.2       
#> [49] rstudioapi_0.11   htmlwidgets_1.5.1 crosstalk_1.1.0.1 mosaicCore_0.6.0 
#> [53] rmarkdown_2.3     gtable_0.3.0      codetools_0.2-16  DBI_1.1.0        
#> [57] R6_2.4.1          gridExtra_2.3     lubridate_1.7.9   knitr_1.29       
#> [61] stringi_1.4.6     Rcpp_1.0.5        vctrs_0.3.4       leaflet_2.0.3    
#> [65] dbplyr_1.4.4      tidyselect_1.1.0  xfun_0.16

Das ist ein ERbie:

  • einfach: kein unnötiger Code, wenig Daten, alles einfach gehalten
  • reproduzierbar: alle wesentlichen Infos sind enthalten – der Empfänger kann den Code durchlaufen lassen

Keine Screenshots mit R-Code

Screenshots zwingen die Person, die Ihnen helfen will, den Code unnötigerweise abzutippen. Sie erzeugen unnötige Arbeit für jemanden, der Ihnen helfen will. Das ist nicht gerade höflich.

Frage: “Aber wie kriege ich die R-Ausgabe ohne Screenshots, sondern als Text produziert?”

Antwort: Erzeugen Sie ein Rmd-Dokument oder nutzen Sie die Reprex-Technik. Hier ist ein schöner Vortrag der Autorin, Jenny Bryan, dazu.

Reprex

Das R-Paket reprex (Reprex) hilft Ihnen, ERBIEs zu erstellen. Es ist eine Alternative zu einer Rmd-Datei.

Messlatte: Ich kann Ihren Code copy-pasten

Die Messlatte ist: Ich kann Ihren Code copy-pasten und alles läuft – nur an der einen Stelle, wo Sie nicht weiterkommen, wird ein Fehler angezeigt.

Informationen an den Retter, außerhalb des R-Codes

Wenn Sie eine Person anschreiben, von der Sie Hilfe erwarten, sollten Sie neben dem R-Code noch ein paar Sachen dazu schreiben:

  • Das habe ich schon probiert, …
  • Diese ähnlichen Beispiele habe ich gefunden, aber Sie passen nicht …
  • Ich vermute, es könnte an … liegen
  • Fügen Sie einen aussagekräften Titel hinzu.

Stack Overflow der Ort für “Hier-werden-Sie-geholfen”

Der bekannteste Ort, um Hilfe bei Programmierproblemen (wie R) zu bekommen, ist das Forum Stackoverflow. Natürlich gelten dort die gleichen (bzw. ähnlichen) Regeln wie die, ich gerade hier formuliert habe. Sie finden entsprechende Hinweise hier oder hier.

Nennen wir es die 30-Minuten-Schlaf-drüber-10-Webseiten-Regel. Bevor Sie jemanden um Hilfe bitten, sollten Sie sich ernsthaft selber bemüht haben:

PS: “Hey, so ein ERBIE ist echt viel Aufwand!”

Ja, das stimmt. Aber der insgesamte Aufwand (für alle beteiligten Personen) sinkt. Außerdem bitten Sie eine andere Person, dass diese für Sie Zeit investiert, um Ihre Probleme zu lösen. Da sollten Sie dieser “Hilfskraft” ein Stück entgegenkommen, das ist nur fair.