Wenn Sie mit Kollegen über Leistung diskutieren, unterrichten, einen Fehlerbericht senden oder nach Anleitungen für Mailinglisten und hier für Stack Overflow suchen, wird häufig ein reproduzierbares Beispiel gefragt und ist immer hilfreich.
Was sind Ihre Tipps, um ein hervorragendes Beispiel zu schaffen? Wie fügt man Datenstrukturen aus r in ein Textformat ein? Welche weiteren Informationen sollten Sie hinzufügen?
Gibt es andere Tricks zusätzlich zur Verwendung von dput()
, dump()
oder structure()
? Wann sollten Sie library()
- oder require()
-Anweisungen einfügen? Welche reservierten Wörter sollte man zusätzlich zu c
, df
, data
usw. vermeiden?
Wie macht man ein gutes r reproduzierbares Beispiel?
Ein minimal reproduzierbares Beispiel besteht aus folgenden Elementen:
set.seed()
) für die Reproduzierbarkeit Wichtiger Hinweis: Die Ausgabe von set.seed()
unterscheidet sich zwischen R> 3.6.0 und früheren Versionen. Geben Sie an, welche R-Version Sie für den Zufallsprozess verwendet haben.
Ein Blick auf die Beispiele in den Hilfedateien der verwendeten Funktionen ist oft hilfreich. Im Allgemeinen erfüllt der dort angegebene Code die Anforderungen eines minimal reproduzierbaren Beispiels: Daten werden bereitgestellt, minimaler Code wird bereitgestellt und alles ist ausführbar.
In den meisten Fällen kann dies einfach durch Bereitstellen eines Vektor-/Datenrahmens mit einigen Werten erfolgen. Sie können auch einen der integrierten Datasets verwenden, die in den meisten Paketen enthalten sind.
Eine umfassende Liste der eingebauten Datensätze kann mit library(help = "datasets")
angezeigt werden. Zu jedem Datensatz gibt es eine kurze Beschreibung. Weitere Informationen erhalten Sie beispielsweise mit ?mtcars
, wobei 'mtcars' einer der Datensätze in der Liste ist. Andere Pakete enthalten möglicherweise zusätzliche Datensätze.
Einen Vektor zu erstellen ist einfach. Manchmal muss etwas Zufälliges hinzugefügt werden, und dafür gibt es eine ganze Reihe von Funktionen. sample()
kann einen Vektor randomisieren oder einen zufälligen Vektor mit nur wenigen Werten angeben. letters
ist ein nützlicher Vektor, der das Alphabet enthält. Dies kann zur Herstellung von Faktoren verwendet werden.
Einige Beispiele:
x <- rnorm(10)
für Normalverteilung, x <- runif(10)
für Gleichverteilung, ...x <- sample(1:10)
für den Vektor 1:10 in zufälliger Reihenfolge.x <- sample(letters[1:4], 20, replace = TRUE)
Für Matrizen kann man matrix()
verwenden, zB:
matrix(1:10, ncol = 2)
Datenrahmen können mit data.frame()
erstellt werden. Man sollte darauf achten, die Einträge im Datenrahmen zu benennen und nicht zu kompliziert zu machen.
Ein Beispiel :
set.seed(1)
Data <- data.frame(
X = sample(1:10),
Y = sample(c("yes", "no"), 10, replace = TRUE)
)
Bei einigen Fragen können spezielle Formate erforderlich sein. Für diese kann man jede der bereitgestellten as.someType
-Funktionen verwenden: as.factor
, as.Date
, as.xts
, ... Diese in Kombination mit den Vektor- und/oder Datenrahmen-Tricks .
Wenn Sie Daten haben, die sich mit diesen Tipps nur schwer konstruieren lassen, können Sie immer eine Teilmenge Ihrer ursprünglichen Daten erstellen, z. B. mit head()
, subset()
oder den Indizes. Dann benutze zB. dput()
um uns etwas zu geben, das sofort in R eingegeben werden kann:
> dput(head(iris,4))
structure(list(Sepal.Length = c(5.1, 4.9, 4.7, 4.6), Sepal.Width = c(3.5,
3, 3.2, 3.1), Petal.Length = c(1.4, 1.4, 1.3, 1.5), Petal.Width = c(0.2,
0.2, 0.2, 0.2), Species = structure(c(1L, 1L, 1L, 1L), .Label = c("setosa",
"versicolor", "virginica"), class = "factor")), .Names = c("Sepal.Length",
"Sepal.Width", "Petal.Length", "Petal.Width", "Species"), row.names = c(NA,
4L), class = "data.frame")
Wenn Ihr Datenrahmen einen Faktor mit vielen Ebenen hat, kann die Ausgabe von dput
unhandlich sein, da immer noch alle möglichen Faktorebenen aufgelistet werden, auch wenn sie nicht in der Teilmenge Ihrer Daten vorhanden sind. Um dieses Problem zu beheben, können Sie die Funktion droplevels()
verwenden. Beachten Sie unten, wie Arten ein Faktor mit nur einer Ebene sind:
> dput(droplevels(head(iris, 4)))
structure(list(Sepal.Length = c(5.1, 4.9, 4.7, 4.6), Sepal.Width = c(3.5,
3, 3.2, 3.1), Petal.Length = c(1.4, 1.4, 1.3, 1.5), Petal.Width = c(0.2,
0.2, 0.2, 0.2), Species = structure(c(1L, 1L, 1L, 1L), .Label = "setosa",
class = "factor")), .Names = c("Sepal.Length", "Sepal.Width",
"Petal.Length", "Petal.Width", "Species"), row.names = c(NA,
4L), class = "data.frame")
Eine weitere Einschränkung für dput
ist, dass es nicht für verschlüsselte data.table
-Objekte oder für gruppierte tbl_df
(Klasse grouped_df
) aus dplyr
funktioniert. In diesen Fällen können Sie vor der Freigabe dput(as.data.frame(my_data))
wieder in einen regulären Datenrahmen konvertieren.
Im schlimmsten Fall können Sie eine Textdarstellung angeben, die mit dem Parameter text
von read.table
eingelesen werden kann:
zz <- "Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa"
Data <- read.table(text=zz, header = TRUE)
Dies sollte der einfache Teil sein, ist es aber oft nicht. Was Sie nicht tun sollten, ist:
Was Sie tun sollten, ist:
library()
)unlink()
).op <- par(mfrow=c(1,2)) ...some code... par(op)
)In den meisten Fällen reichen nur die R-Version und das Betriebssystem aus. Wenn Konflikte mit Paketen auftreten, kann die Ausgabe von sessionInfo()
wirklich hilfreich sein. Wenn es um Verbindungen zu anderen Anwendungen geht (sei es über ODBC oder irgendetwas anderes), sollte man auch Versionsnummern für diese und wenn möglich auch die notwendigen Informationen zum Setup bereitstellen.
Wenn Sie R in R Studio mit rstudioapi::versionInfo()
ausführen, kann dies hilfreich sein, um Ihre RStudio-Version zu melden.
Wenn Sie ein Problem mit einem bestimmten Paket haben, möchten Sie möglicherweise die Version des Pakets bereitstellen, indem Sie die Ausgabe von packageVersion("name of the package")
angeben.
(Hier ist mein Rat von Wie schreibe ich ein reproduzierbares Beispiel . Ich habe versucht, es kurz, aber süß zu machen)
Am ehesten erhalten Sie bei Ihrem R-Problem Hilfe, wenn Sie ein reproduzierbares Beispiel angeben. Ein reproduzierbares Beispiel ermöglicht es einer anderen Person, Ihr Problem durch einfaches Kopieren und Einfügen von R-Code wiederherzustellen.
Es gibt vier Dinge, die Sie einschließen müssen, um Ihr Beispiel reproduzierbar zu machen: erforderliche Pakete, Daten, Code und eine Beschreibung Ihrer R-Umgebung.
Pakete sollten oben im Skript geladen werden, damit Sie leicht erkennen können, welche das Beispiel benötigt.
Der einfachste Weg, Daten in eine E-Mail- oder Stapelüberlauf-Frage aufzunehmen , ist die Verwendung von dput()
, um den R-Code für die Neuerstellung zu generieren. Um beispielsweise das mtcars
-Dataset in R neu zu erstellen, führen Sie die folgenden Schritte aus:
dput(mtcars)
in R ausmtcars <-
ein und fügen Sie es ein.Verbringen Sie ein wenig Zeit damit, sicherzustellen, dass Ihr Code für andere leicht lesbar ist:
stellen Sie sicher, dass Sie Leerzeichen verwendet haben und Ihre Variablennamen präzise, aber informativ sind
verwenden Sie Kommentare, um anzugeben, wo Ihr Problem liegt
geben Sie Ihr Bestes, um alles zu entfernen, was nicht mit dem Problem zusammenhängt.
Je kürzer Ihr Code ist, desto einfacher ist es zu verstehen.
Fügen Sie die Ausgabe von sessionInfo()
in einen Kommentar in Ihrem Code ein. Dies fasst Ihre R-Umgebung zusammen und erleichtert die Überprüfung, ob Sie ein veraltetes Paket verwenden.
Sie können überprüfen, ob Sie tatsächlich ein reproduzierbares Beispiel erstellt haben, indem Sie eine neue R-Sitzung starten und Ihr Skript einfügen.
Bevor Sie Ihren gesamten Code in eine E-Mail einfügen, sollten Sie ihn auf Gist github setzen. Es gibt Ihrem Code eine schöne Hervorhebung der Syntax und Sie müssen sich keine Sorgen machen, dass das E-Mail-System etwas kaputt macht.
Persönlich bevorzuge ich "one" Liner. Etwas in die richtige Richtung:
my.df <- data.frame(col1 = sample(c(1,2), 10, replace = TRUE),
col2 = as.factor(sample(10)), col3 = letters[1:10],
col4 = sample(c(TRUE, FALSE), 10, replace = TRUE))
my.list <- list(list1 = my.df, list2 = my.df[3], list3 = letters)
Die Datenstruktur sollte die Idee des Schreibproblems nachahmen und nicht die genaue wörtliche Struktur. Ich weiß es wirklich zu schätzen, wenn Variablen meine eigenen Variablen nicht überschreiben oder Funktionen (wie df
) verbieten.
Alternativ könnte man ein paar Ecken abschneiden und auf einen bereits vorhandenen Datensatz verweisen, etwa:
library(vegan)
data(varespec)
ord <- metaMDS(varespec)
Vergessen Sie nicht, spezielle Pakete anzugeben, die Sie möglicherweise verwenden.
Wenn Sie versuchen, etwas an größeren Objekten zu demonstrieren, können Sie es versuchen
my.df2 <- data.frame(a = sample(10e6), b = sample(letters, 10e6, replace = TRUE))
Wenn Sie mit Geodaten über das Paket raster
arbeiten, können Sie einige zufällige Daten generieren. Viele Beispiele finden Sie in der Paketvignette, aber hier ist ein kleines Nugget.
library(raster)
r1 <- r2 <- r3 <- raster(nrow=10, ncol=10)
values(r1) <- runif(ncell(r1))
values(r2) <- runif(ncell(r2))
values(r3) <- runif(ncell(r3))
s <- stack(r1, r2, r3)
Wenn Sie ein räumliches Objekt benötigen, wie es in sp
implementiert ist, können Sie einige Datensätze über externe Dateien (z. B. ESRI-Shapefile) in "räumlichen" Paketen abrufen (siehe die räumliche Ansicht in Task-Ansichten).
library(rgdal)
ogrDrivers()
dsn <- system.file("vectors", package = "rgdal")[1]
ogrListLayers(dsn)
ogrInfo(dsn=dsn, layer="cities")
cities <- readOGR(dsn=dsn, layer="cities")
Inspiriert von diesem Beitrag verwende ich jetzt eine praktische Funktionreproduce(<mydata>)
wenn ich auf StackOverflow posten muss.
Wenn myData
der Name Ihres zu reproduzierenden Objekts ist, führen Sie in R Folgendes aus:
install.packages("devtools")
library(devtools)
source_url("https://raw.github.com/rsaporta/pubR/gitbranch/reproduce.R")
reproduce(myData)
Diese Funktion ist ein intelligenter Wrapper für dput
und führt folgende Aktionen aus:
dput
AusgabeobjName <- ...
, damit es leicht kopiert und eingefügt werden kann, aber ...# sample data
DF <- data.frame(id=rep(LETTERS, each=4)[1:100], replicate(100, sample(1001, 100)), Class=sample(c("Yes", "No"), 100, TRUE))
DF ist ungefähr 100 x 102. Ich möchte 10 Zeilen und einige bestimmte Spalten abtasten
reproduce(DF, cols=c("id", "X1", "X73", "Class")) # I could also specify the column number.
This is what the sample looks like:
id X1 X73 Class
1 A 266 960 Yes
2 A 373 315 No Notice the selection split
3 A 573 208 No (which can be turned off)
4 A 907 850 Yes
5 B 202 46 Yes
6 B 895 969 Yes <~~~ 70 % of selection is from the top rows
7 B 940 928 No
98 Y 371 171 Yes
99 Y 733 364 Yes <~~~ 30 % of selection is from the bottom rows.
100 Y 546 641 No
==X==============================================================X==
Copy+Paste this part. (If on a Mac, it is already copied!)
==X==============================================================X==
DF <- structure(list(id = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 25L, 25L, 25L), .Label = c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y"), class = "factor"), X1 = c(266L, 373L, 573L, 907L, 202L, 895L, 940L, 371L, 733L, 546L), X73 = c(960L, 315L, 208L, 850L, 46L, 969L, 928L, 171L, 364L, 641L), Class = structure(c(2L, 1L, 1L, 2L, 2L, 2L, 1L, 2L, 2L, 1L), .Label = c("No", "Yes"), class = "factor")), .Names = c("id", "X1", "X73", "Class"), class = "data.frame", row.names = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 98L, 99L, 100L))
==X==============================================================X==
Beachten Sie auch, dass sich die gesamte Ausgabe in einer einzigen, langen Zeile befindet, nicht in einem hohen Absatz aus zerlegten Zeilen. Dies erleichtert das Lesen von SO Fragenbeiträgen und das Kopieren und Einfügen.
Sie können jetzt festlegen, wie viele Zeilen Text ausgegeben werden sollen (dh was Sie in StackOverflow einfügen). Verwenden Sie dazu das Argument lines.out=n
. Beispiel:
reproduce(DF, cols=c(1:3, 17, 23), lines.out=7)
ergibt:
==X==============================================================X==
Copy+Paste this part. (If on a Mac, it is already copied!)
==X==============================================================X==
DF <- structure(list(id = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 25L,25L, 25L), .Label
= c("A", "B", "C", "D", "E", "F", "G", "H","I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U","V", "W", "X", "Y"), class = "factor"),
X1 = c(809L, 81L, 862L,747L, 224L, 721L, 310L, 53L, 853L, 642L),
X2 = c(926L, 409L,825L, 702L, 803L, 63L, 319L, 941L, 598L, 830L),
X16 = c(447L,164L, 8L, 775L, 471L, 196L, 30L, 420L, 47L, 327L),
X22 = c(335L,164L, 503L, 407L, 662L, 139L, 111L, 721L, 340L, 178L)), .Names = c("id","X1",
"X2", "X16", "X22"), class = "data.frame", row.names = c(1L,2L, 3L, 4L, 5L, 6L, 7L, 98L, 99L, 100L))
==X==============================================================X==
Hier ist eine gute Anleitung .
Der wichtigste Punkt ist: Stellen Sie einfach sicher, dass Sie einen kleinen Code erstellen, den wir ausführen können, um das Problem zu erkennen . Eine nützliche Funktion hierfür ist dput()
. Wenn Sie jedoch sehr große Datenmengen haben, möchten Sie möglicherweise einen kleinen Beispieldatensatz erstellen oder nur die ersten 10 Zeilen oder so verwenden.
EDIT:
Stellen Sie außerdem sicher, dass Sie selbst identifiziert haben, wo das Problem liegt. Das Beispiel sollte kein vollständiges R-Skript mit "In Zeile 200 liegt ein Fehler vor" sein. Wenn Sie die Debugging-Tools in R (ich liebe browser()
) und Google verwenden, sollten Sie in der Lage sein, das Problem wirklich zu identifizieren und ein einfaches Beispiel zu reproduzieren, in dem dasselbe schief geht.
Die R-Help-Mailingliste enthält eine Posting-Anleitung , die sowohl das Stellen als auch das Beantworten von Fragen abdeckt, einschließlich eines Beispiels für das Generieren von Daten:
Beispiele: Manchmal ist es hilfreich, ein kleines Beispiel anzugeben, das tatsächlich von jemandem ausgeführt werden kann. Zum Beispiel:
Wenn ich eine Matrix x wie folgt habe:
> x <- matrix(1:8, nrow=4, ncol=2,
dimnames=list(c("A","B","C","D"), c("x","y"))
> x
x y
A 1 5
B 2 6
C 3 7
D 4 8
>
wie kann ich daraus einen Datenrahmen mit 8 Zeilen und drei Spalten namens 'row', 'col' und 'value' machen, deren Dimensionsnamen die Werte von 'row' und 'col' sind?
> x.df
row col value
1 A x 1
...
(Worauf die Antwort lauten könnte:
> x.df <- reshape(data.frame(row=rownames(x), x), direction="long",
varying=list(colnames(x)), times=colnames(x),
v.names="value", timevar="col", idvar="row")
)
Das Wort klein ist besonders wichtig. Sie sollten ein minimales reproduzierbares Beispiel anstreben, was bedeutet, dass die Daten und der Code so einfach wie möglich sein sollten, um das Problem zu erklären.
BEARBEITEN: Hübscher Code ist leichter zu lesen als hässlicher Code. Verwenden Sie ein Formatvorlage .
Seit R.2.14 können Sie Ihre Datentextdarstellung direkt an read.table
übergeben:
df <- read.table(header=TRUE,
text="Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
")
Manchmal ist das Problem mit einer kleineren Datenmenge wirklich nicht reproduzierbar, unabhängig davon, wie sehr Sie es versuchen, und tritt auch bei synthetischen Daten nicht auf (obwohl es nützlich ist, zu zeigen, wie Sie synthetische Datensätze erstellt haben, die reproduziere das Problem nicht , da es einige Hypothesen ausschließt).
Wenn Sie beides nicht können, müssen Sie wahrscheinlich einen Berater beauftragen, um Ihr Problem zu lösen ...
edit : Zwei nützliche SO Fragen zur Anonymisierung/Verschlüsselung:
Die bisherigen Antworten sind offensichtlich großartig für den Teil der Reproduzierbarkeit. Dies soll lediglich klarstellen, dass ein reproduzierbares Beispiel nicht der einzige Bestandteil einer Frage sein kann und sollte. Vergessen Sie nicht zu erklären, wie es aussehen soll und wie sich Ihr Problem entwickelt, und nicht nur, wie Sie bisher versucht haben, dorthin zu gelangen. Code ist nicht genug; du brauchst auch Worte.
Hier ist ein reproduzierbares Beispiel dafür, was Sie vermeiden sollten (anhand eines realen Beispiels wurden die Namen geändert, um die Unschuldigen zu schützen):
Das Folgende sind Beispieldaten und ein Teil der Funktion, mit der ich Probleme habe.
code
code
code
code
code (40 or so lines of it)
Wie kann ich das erreichen?
Ich habe eine sehr einfache und effiziente Möglichkeit, ein R-Beispiel zu erstellen, das oben nicht erwähnt wurde. Sie können zunächst Ihre Struktur definieren. Zum Beispiel,
mydata <- data.frame(a=character(0), b=numeric(0), c=numeric(0), d=numeric(0))
>fix(mydata)
Dann können Sie Ihre Daten manuell eingeben. Dies ist für kleinere Beispiele effizienter als für große.
Um schnell ein dput
Ihrer Daten zu erstellen, können Sie die Daten einfach (teilweise) in Ihre Zwischenablage kopieren und Folgendes in R ausführen:
für Daten in Excel:
dput(read.table("clipboard",sep="\t",header=TRUE))
für Daten in einer txt-Datei:
dput(read.table("clipboard",sep="",header=TRUE))
Sie können bei Bedarf das sep
in letzterem ändern. Dies funktioniert natürlich nur, wenn sich Ihre Daten in der Zwischenablage befinden.
Ihr Hauptziel bei der Bearbeitung Ihrer Fragen sollte es sein, es den Lesern so einfach wie möglich zu machen, Ihr Problem auf ihren Systemen zu verstehen und zu reproduzieren. Um dies zu tun:
Dies erfordert einige Arbeit, scheint jedoch ein fairer Kompromiss zu sein, da Sie andere bitten, für Sie zu arbeiten.
Die beste Option bei weitem ist, sich auf integrierte Datasets zu verlassen. Dies macht es für andere sehr einfach, an Ihrem Problem zu arbeiten. Geben Sie an der Eingabeaufforderung R data()
ein, um zu sehen, welche Daten für Sie verfügbar sind. Einige klassische Beispiele:
iris
mtcars
ggplot2::diamonds
(externes Paket, aber fast jeder hat es)In diesem SO QA erfahren Sie, wie Sie für Ihr Problem geeignete Datensätze finden.
Wenn Sie in der Lage sind, Ihr Problem neu zu formulieren, um die integrierten Datensätze zu verwenden, erhalten Sie mit größerer Wahrscheinlichkeit gute Antworten (und positive Bewertungen).
Wenn Ihr Problem sehr spezifisch für einen Datentyp ist, der nicht in den vorhandenen Datensätzen enthalten ist, geben Sie den R-Code an, der den kleinsten möglichen Datensatz generiert dass sich dein problem an manifestiert. Zum Beispiel
set.seed(1) # important to make random data reproducible
myData <- data.frame(a=sample(letters[1:5], 20, rep=T), b=runif(20))
Jetzt kann jemand, der versucht, meine Frage zu beantworten, diese beiden Zeilen kopieren/einfügen und sofort mit der Bearbeitung des Problems beginnen.
Als letzte Möglichkeit können Sie dput
verwenden, um ein Datenobjekt in R-Code umzuwandeln (z. B. dput(myData)
). Ich sage als "letzter Ausweg", weil die Ausgabe von dput
oft ziemlich unhandlich ist, das Kopieren und Einfügen stört und den Rest Ihrer Frage verdeckt.
Jemand sagte einmal:
Ein Bild der erwarteten Ausgabe sagt mehr als 1000 Worte
- eine sehr weise Person
Wenn Sie etwas wie "Ich habe erwartet, dass ich dieses Ergebnis erhalte" hinzufügen können:
cyl mean.hp
1: 6 122.28571
2: 4 82.63636
3: 8 209.21429
in Bezug auf Ihre Frage ist es viel wahrscheinlicher, dass die Leute schnell verstehen, was Sie versuchen. Wenn Ihr erwartetes Ergebnis groß und unhandlich ist, haben Sie wahrscheinlich nicht genug darüber nachgedacht, wie Sie Ihr Problem vereinfachen können (siehe weiter unten).
Die Hauptsache ist, Ihr Problem so weit wie möglich zu vereinfachen, bevor Sie Ihre Frage stellen. Das Problem mit den eingebauten Datensätzen neu zu gestalten, wird in dieser Hinsicht sehr hilfreich sein. Sie werden auch oft feststellen, dass Sie Ihr eigenes Problem lösen, wenn Sie den Vereinfachungsprozess durchlaufen.
Hier einige Beispiele für gute Fragen:
In beiden Fällen liegen die Probleme des Benutzers mit ziemlicher Sicherheit nicht in den einfachen Beispielen. Vielmehr haben sie die Natur ihres Problems abstrahiert und es auf einen einfachen Datensatz angewendet, um ihre Frage zu stellen.
Diese Antwort konzentriert sich auf das, was meiner Meinung nach die beste Vorgehensweise ist: Verwenden Sie integrierte Datensätze und stellen Sie das, was Sie erwarten, in minimaler Form zur Verfügung. Die wichtigsten Antworten konzentrieren sich auf andere Aspekte. Ich erwarte nicht, dass diese Antwort zu irgendeiner Berühmtheit aufsteigt. Dies ist hier nur, damit ich in Kommentaren zu neuen Fragen darauf verlinken kann.
Reproduzierbarer Code ist der Schlüssel, um Hilfe zu erhalten. Es gibt jedoch viele Benutzer, die skeptisch sind, auch nur einen Teil ihrer Daten einzufügen. Beispielsweise könnten sie mit vertraulichen Daten oder mit Originaldaten arbeiten, die zur Verwendung in einem Forschungsbericht gesammelt wurden. Aus irgendeinem Grund dachte ich, es wäre schön, eine praktische Funktion zum "Verformen" meiner Daten zu haben, bevor sie öffentlich eingefügt werden. Die anonymize
-Funktion aus dem Paket SciencesPo
ist sehr albern, aber für mich funktioniert es gut mit der dput
-Funktion.
install.packages("SciencesPo")
dt <- data.frame(
Z = sample(LETTERS,10),
X = sample(1:10),
Y = sample(c("yes", "no"), 10, replace = TRUE)
)
> dt
Z X Y
1 D 8 no
2 T 1 yes
3 J 7 no
4 K 6 no
5 U 2 no
6 A 10 yes
7 Y 5 no
8 M 9 yes
9 X 4 yes
10 Z 3 no
Dann anonymisiere ich es:
> anonymize(dt)
Z X Y
1 b2 2.5 c1
2 b6 -4.5 c2
3 b3 1.5 c1
4 b4 0.5 c1
5 b7 -3.5 c1
6 b1 4.5 c2
7 b9 -0.5 c1
8 b5 3.5 c2
9 b8 -1.5 c2
10 b10 -2.5 c1
Möglicherweise möchten Sie auch einige Variablen anstelle der gesamten Daten abtasten, bevor Sie den Anonymisierungs- und Dput-Befehl anwenden.
# sample two variables without replacement
> anonymize(sample.df(dt,5,vars=c("Y","X")))
Y X
1 a1 -0.4
2 a1 0.6
3 a2 -2.4
4 a1 -1.4
5 a2 3.6
Oft benötigen Sie einige Daten für ein Beispiel, möchten jedoch nicht Ihre genauen Daten veröffentlichen. Um einen vorhandenen data.frame in einer vorhandenen Bibliothek zu verwenden, importieren Sie ihn mit dem Befehl data.
z.B.,
data(mtcars)
und dann mach das problem
names(mtcars)
your problem demostrated on the mtcars data set
Ich entwickle das wakefield Paket , um dieses Bedürfnis schnell zu teilen, anzusprechen Reproduzierbare Daten, manchmal dput
funktionieren gut für kleinere Datenmengen, aber viele der Probleme, mit denen wir zu tun haben, sind viel größer. Die gemeinsame Nutzung einer so großen Datenmenge über dput
ist unpraktisch.
Über:
Mit wakefield kann der Benutzer minimalen Code für die Wiedergabe von Daten freigeben. Der Benutzer legt n
(Anzahl der Zeilen) fest und gibt eine beliebige Anzahl von voreingestellten Variablenfunktionen an (derzeit gibt es 70), die reale Daten imitieren (z. B. Geschlecht, Alter, Einkommen usw.).
Installation:
Derzeit (11.06.2015) ist wakefield ein GitHub Paket, wird aber irgendwann nach dem Schreiben von Komponententests an CRAN gesendet. Verwenden Sie zur schnellen Installation:
if (!require("pacman")) install.packages("pacman")
pacman::p_load_gh("trinker/wakefield")
Beispiel:
Hier ist ein Beispiel:
r_data_frame(
n = 500,
id,
race,
age,
sex,
hour,
iq,
height,
died
)
Dies erzeugt:
ID Race Age Sex Hour IQ Height Died
1 001 White 33 Male 00:00:00 104 74 TRUE
2 002 White 24 Male 00:00:00 78 69 FALSE
3 003 Asian 34 Female 00:00:00 113 66 TRUE
4 004 White 22 Male 00:00:00 124 73 TRUE
5 005 White 25 Female 00:00:00 95 72 TRUE
6 006 White 26 Female 00:00:00 104 69 TRUE
7 007 Black 30 Female 00:00:00 111 71 FALSE
8 008 Black 29 Female 00:00:00 100 64 TRUE
9 009 Asian 25 Male 00:30:00 106 70 FALSE
10 010 White 27 Male 00:30:00 121 68 FALSE
.. ... ... ... ... ... ... ... ...
Wenn Ihre Daten eine oder mehrere factor
Variable (n) enthalten, die Sie mit dput(head(mydata))
reproduzieren möchten, sollten Sie droplevels
hinzufügen, damit die Ebenen der Faktoren nicht vorhanden sind im minimierten Datensatz sind nicht in Ihrer dput
Ausgabe enthalten, um das Beispiel zu machen minimal:
dput(droplevels(head(mydata)))
Ich frage mich, ob ein http://old.r-fiddle.org/ Link eine sehr gute Möglichkeit ist, ein Problem zu teilen. Es erhält eine eindeutige ID wie und man könnte sogar darüber nachdenken, es in SO einzubetten.
Bitte fügen Sie Ihre Konsolenausgaben nicht so ein:
If I have a matrix x as follows:
> x <- matrix(1:8, nrow=4, ncol=2,
dimnames=list(c("A","B","C","D"), c("x","y")))
> x
x y
A 1 5
B 2 6
C 3 7
D 4 8
>
How can I turn it into a dataframe with 8 rows, and three
columns named `row`, `col`, and `value`, which have the
dimension names as the values of `row` and `col`, like this:
> x.df
row col value
1 A x 1
...
(To which the answer might be:
> x.df <- reshape(data.frame(row=rownames(x), x), direction="long",
+ varying=list(colnames(x)), times=colnames(x),
+ v.names="value", timevar="col", idvar="row")
)
Wir können es nicht direkt kopieren und einfügen.
Versuchen Sie, +
& >
vor dem Posten zu entfernen und #
für Ausgaben und Kommentare wie diese zu setzen, um die Reproduzierbarkeit von Fragen und Antworten zu gewährleisten:
#If I have a matrix x as follows:
x <- matrix(1:8, nrow=4, ncol=2,
dimnames=list(c("A","B","C","D"), c("x","y")))
x
# x y
#A 1 5
#B 2 6
#C 3 7
#D 4 8
# How can I turn it into a dataframe with 8 rows, and three
# columns named `row`, `col`, and `value`, which have the
# dimension names as the values of `row` and `col`, like this:
#x.df
# row col value
#1 A x 1
#...
#To which the answer might be:
x.df <- reshape(data.frame(row=rownames(x), x), direction="long",
varying=list(colnames(x)), times=colnames(x),
v.names="value", timevar="col", idvar="row")
Wenn Sie eine Funktion aus einem bestimmten Paket verwendet haben, erwähnen Sie diese Bibliothek.
Abgesehen von allen obigen Antworten, die ich sehr interessant fand, konnte es manchmal sehr einfach sein, wie hier besprochen wird: - WIE MAN EIN MINIMALES REPRODUZIERBARES BEISPIEL MACHT, UM HILFE BEI R ZU ERHALTEN
Es gibt viele Möglichkeiten, einen Zufallsvektor zu erstellen Erstellen Sie einen Vektor mit 100 Zahlen mit Zufallswerten in R, die auf 2 Dezimalstellen gerundet sind oder eine Zufallsmatrix in R
mydf1<- matrix(rnorm(20),nrow=20,ncol=5)
Beachten Sie, dass es manchmal aus verschiedenen Gründen, wie z. B. der Dimension usw., sehr schwierig ist, bestimmte Daten gemeinsam zu nutzen. Alle oben genannten Antworten sind jedoch großartig und sehr wichtig, wenn Sie ein Beispiel für reproduzierbare Daten erstellen möchten. Beachten Sie jedoch, dass, um Daten so repräsentativ wie das Original zu machen (falls das OP die Originaldaten nicht teilen kann), einige Informationen mit dem Datenbeispiel hinzugefügt werden sollten (wenn wir die Daten mydf1 nennen).
class(mydf1)
# this shows the type of the data you have
dim(mydf1)
# this shows the dimension of your data
Darüber hinaus sollte man den Typ, die Länge und die Attribute von Daten kennen, die Datenstrukturen sein können
#found based on the following
typeof(mydf1), what it is.
length(mydf1), how many elements it contains.
attributes(mydf1), additional arbitrary metadata.
#If you cannot share your original data, you can str it and give an idea about the structure of your data
head(str(mydf1))
Sie können dies mit reprex tun.
Wie mt1022 vermerkt "... ist eine gute Verpackung zur Herstellung eines minimalen, reproduzierbaren Beispiels " reprex " von tidyverse ".
Nach Tidyverse :
Das Ziel von "reprex" ist es, Ihren problematischen Code so zu verpacken, dass andere ihn ausführen und Ihren Schmerz spüren können.
Ein Beispiel finden Sie auf der Website tidyverse .
library(reprex)
y <- 1:4
mean(y)
reprex()
Ich denke das ist der einfachste Weg ein reproduzierbares Beispiel zu erstellen.
Hier sind einige meiner Vorschläge:
dput
ein, damit andere Ihnen leichter helfen könneninstall.package()
nur, wenn dies wirklich notwendig ist. Die Leute werden verstehen, wenn Sie require
oder library
verwenden.Versuchen Sie, prägnant zu sein,
All dies ist Teil eines reproduzierbaren Beispiels.
Es ist eine gute Idee, Funktionen aus dem Paket testthat
zu verwenden, um zu zeigen, was Sie erwarten. Auf diese Weise können andere Benutzer Ihren Code so lange ändern, bis er fehlerfrei ausgeführt wird. Dies entlastet diejenigen, die Ihnen helfen möchten, da sie Ihre Textbeschreibung nicht entschlüsseln müssen. Zum Beispiel
library(testthat)
# code defining x and y
if (y >= 10) {
expect_equal(x, 1.23)
} else {
expect_equal(x, 3.21)
}
ist klarer als "Ich denke, x wäre 1,23 für y gleich oder größer als 10 und 3,21 sonst, aber ich habe kein Ergebnis". Sogar in diesem albernen Beispiel denke ich, dass der Code klarer als die Wörter ist. Durch die Verwendung von testthat
kann sich Ihr Helfer auf den Code konzentrieren, was Zeit spart und es ermöglicht, dass er weiß, dass er Ihr Problem gelöst hat, bevor er es veröffentlicht