Wie erstelle ich ein reproduzierbares Beispiel? [work in progress]

Wiederkehrende Fragen zum Forum

Moderator: EDi

Antworten
Benutzeravatar
EDi
Beiträge: 1602
Registriert: Sa Okt 08, 2016 3:39 pm

Wie erstelle ich ein reproduzierbares Beispiel? [work in progress]

Beitrag von EDi »

1. Warum ein reproduzierbares Beispiel?


1.1 Häufige Probleme
Bevor ihr eine Frage posten, überprüft vorher ob die folgenden Punkte:
  • Daten richtig eingelesen?
    Bitte nach jedem einlesen mit ?str überprüfen ob der Datz auch so aussieht wie ihr euch das vorstellt

    Code: Alles auswählen

    str(Formaldehyde)
    # 'data.frame':	6 obs. of  3 variables:
    #  $ carb  : num  0.1 0.3 0.5 0.6 0.7 0.9
    #  $ optden: num  0.086 0.269 0.446 0.538 0.626 0.782
    #  $ type  : Factor w/ 6 levels "A","B","C","D",..: 1 2 3 4 5 6
    Hier sehen wir, dass es sich um einen data.frame handelt 6 Zeilen (obs.) und 3 Spalten (variables) hat.
    R hat viele Datenstrukturen, die alle unterschiedliche Eigenschaften haben. Der data.frame ist der häufigste Typ den ihr antreffen und verwenden werden. [Hier gibst eine gute Erklärung und Übersicht].

    Als nächsten folgt für jede Spalten eine Übersicht mit der folgenden Struktur:
    $ <Name> : <Typ> <Einträge>
    Hier ist das wichtigste der Typ:
    Hier findet ihr oft 'num' (Zahlen), 'int' (Ganzzahlen', 'chr' (Zeichenfolgen) oder 'Factor (ein spezieller Typ für kategorische Variablen. Bitte überpüft ob numerische spalten auch als solches erkannt werden.
    Hier ist z.b. etwas mit dem dezimal Trenner (als Komma) schiefgelaufen:

    Code: Alles auswählen

    str(Formaldehyde)
    # 'data.frame':	6 obs. of  3 variables:
    #  $ carb  : chr  "0,1" "0,3" "0,5" "0,6" ...
    #  $ optden: num  0.086 0.269 0.446 0.538 0.626 0.782
    #  $ type  : Factor w/ 6 levels "A","B","C","D",..: 1 2 3 4 5 6
    Das erkennt man daran, dass carb nun ein 'chr' ist [und nicht wie wir erwarten wuerden eine Zahl / 'num'].
    Bei einem Blick auf die Einträge erkennt man dann das Komma.
    Oft kommt es auch vor das Zahlen fälschlicherweise als Faktoren erkannt werden. Hier gilt es dann zu untersuchen, warm R mein, das wären keine Zahlen (NAs, Kommas, komische Werte sind gute Kandidaten).
  • ...
2 . Zutaten für ein reproduzierbares Beispiel
  • Daten
  • Pakete / Versionen
  • lauffähiger Code
3. Daten

Hier gilt: So klein wie möglich [um das Problem zu zeigen] - so groß wie nötig [um das Problem zu verstehen].
Ihr könnt entweder (i) direkt eure Daten posten oder (ii) einen Datensatz der mit R oder einem der Pakete mitgeliefert wird nutzen oder (iii) einen Datensatz selbst erstellen.

3.1 Eigene Daten posten
Das ist die einfachste Variante, falls ihr die Daten öffentlich Zugänglich machen dürft / wollt.
Ihr hab zwei Varianten zur Auswahl:
Rohdaten als Anhang posten (bevorzugt als .csv) oder die Daten im Quelltext kodieren.

Daten im Quelltext kodieren:
Dazu könnt ihr ?dput nutzen.
Angenomme ich habe einen Datensatz Formaldehyde:

Code: Alles auswählen

Formaldehyde
#   carb optden
#  1  0.1  0.086
#  2  0.3  0.269
#  3  0.5  0.446
#  4  0.6  0.538
#  5  0.7  0.626
#  6  0.9  0.782
Dann könnt ihr diesen in R-Code umwandeln mit:

Code: Alles auswählen

dput(Formaldehyde)
#  structure(list(carb = c(0.1, 0.3, 0.5, 0.6, 0.7, 0.9), optden = c(0.086, 
#  0.269, 0.446, 0.538, 0.626, 0.782)), .Names = c("carb", "optden"
#  ), row.names = c("1", "2", "3", "4", "5", "6"), class = "data.frame")
Das sieht jetzt erst mal kompliziert aus und ihr müsst auch nicht verstehen was das bedeutet.
Einfach am Anfang eures Skripts den Namen zuordnen, den ihr verwendet und jder kann den Formaldehyde Datensatz reproduzieren:

Code: Alles auswählen

Formaldehyde <- structure(list(carb = c(0.1, 0.3, 0.5, 0.6, 0.7, 0.9), optden = c(0.086, 
                                                                                  0.269, 0.446, 0.538, 0.626, 0.782)), .Names = c("carb", "optden"
                                                                                  ), row.names = c("1", "2", "3", "4", "5", "6"), class = "data.frame")

Code: Alles auswählen

Formaldehyde
#   carb optden
#  1  0.1  0.086
#  2  0.3  0.269
#  3  0.5  0.446
#  4  0.6  0.538
#  5  0.7  0.626
#  6  0.9  0.782
Falls ihr sehr viele Daten habt, könnt ihr ?head nutzen um nur die ersten x-zeilen zu nehmen:

Code: Alles auswählen

put(head(Formaldehyde, 3))
Für die ersten drei Zeilen.


3.2 Datensätze die mit R oder einem der Pakete mitgeliefert werden
R kommt mit einem Haufen Datensätzen die meist in en Beispielen in den Hilfen verwendet werden.
Ihr könnt euch eine Liste der Datensätze mit Beschriebungen mit

Code: Alles auswählen

 library(help = "datasets")
anzeigen lassen.
Der oben verwendete Formaldehyde Datensatz wird auch mit R mitgeliefert.
Um nähere Infos zu erhalten, schaut euch die Hilfe zu den Datensätzen an:

Code: Alles auswählen

?Formaldehyde
Datensätze die oft für Beispiele verwendet werden sind ?iris (Faktoren/Gruppen), ?mtcars (multivariate kontinuierliche Daten), ?volcano (räumliche Daten) und ?warpbreaks (mixed effects).

Pakete kommen zusätzlich oft mit eigenen Datensätzen. Schaut euch dazu am besten ganz unten auf den Hilfeseiten des Paketes unter 'Examples' den Code an.

3.3 Datensatz selbst erstellen
Das ist am kompliziertesten, aber oft löst ihr euer Problem schon SELBST wenn ihr versucht passende Daten zu erstellen.
Schaut euch vorher an
Am einfachsten ist es Vektoren mit Zufallszahlen zu erstellen und danach zu einem Data.frame zusammenzufügen.
Normalverteile Zufallszahlen kann man mit ?rnorm erstellen, gleichverteilte mit ?runif, mit ?sample kann man Faktoren erstellen. Das könnte dann so aussehen:

Code: Alles auswählen

x <- runif(10)
y <- rnorm(10, x)
fac <- sample(c('A', 'B'), 10, replace = TRUE)
df <- data.frame(x, y, fac)
Wie können die Struktur überprüfen (siehe 1.1), ob das so ist wie wir es haben wollen:

Code: Alles auswählen

> str(df)
# 'data.frame':	10 obs. of  3 variables:
#  $ x  : num  0.535 0.407 0.58 0.557 0.838 ...
#  $ y  : num  0.306 1.306 0.634 2.04 2.026 ...
#  $ fac: Factor w/ 2 levels "A","B": 2 2 2 1 2 1 2 1 1 1
Und hier ein plot der erzeugten Daten:

Code: Alles auswählen

plot(y ~ x, data = df, col = df$fac)
4. Infos zu Paketen und Versionen

Code: Alles auswählen

 sessionInfo()
 
R version 3.3.1 (2016-06-21)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Arch Linux

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] vegan_2.4-1     lattice_0.20-33 permute_0.9-4  

loaded via a namespace (and not attached):
[1] MASS_7.3-45     Matrix_1.2-6    rsconnect_0.4.3 parallel_3.3.1 
[5] tools_3.3.1     mgcv_1.8-12     nlme_3.1-128    grid_3.3.1     
[9] cluster_2.0.4  


5. Lauffähiger Code

Vor dem Posten bitte in einer neuen R-Session bei euch überprüfen ob der Code / das Beispiel den ihr posten wollt auch läuft
Bitte immer ein reproduzierbares Minimalbeispiel angeben. Meinungen gehören mir und geben nicht die meines Brötchengebers wieder.

Dieser Beitrag ist lizensiert unter einer CC BY 4.0 Lizenz
Bild.
Athomas
Beiträge: 776
Registriert: Mo Feb 26, 2018 8:19 pm

Re: Wie erstelle ich ein reproduzierbares Beispiel? [work in progress]

Beitrag von Athomas »

Ich fände es gut, wenn dieser wichtige Beitrag an eine herausgehobenen Stelle gesetzt würde - so, dass kein Neuling daran vorbeikommt und ihn bei Bedarf schnell wiederfindet: etwa im Abschnitt "Rund um das Forum", an erster Stelle unter "Neulinge - bitte unbedingt lesen!" - und dann bitte ohne die Möglichkeit, einen weiteren Eintrag vorzunehmen und den wichtigen Beitrag in den (optischen) Hintergrund zu schieben.
Antworten