Lorsque vous discutez de performances avec vos collègues, que vous enseignez, envoyez un rapport de bogue ou recherchez des conseils sur les listes de diffusion et ici sur Stack Overflow, un exemple reproductible est souvent demandé et toujours utile.
Quels sont vos conseils pour créer un excellent exemple? Comment coller des structures de données de r dans un format texte? Quelles autres informations devriez-vous inclure?
Existe-t-il d'autres astuces en plus de l'utilisation de dput()
, dump()
ou structure()
? Quand faut-il inclure les instructions library()
ou require()
? Quels mots réservés faut-il éviter, en plus de c
, df
, data
, etc.?
Comment fait-on un bon exemple r reproductible?
Un exemple reproductible minimal comprend les éléments suivants:
set.seed()
) pour la reproductibilité remarque importante: La sortie de set.seed()
diffère entre R> 3.6.0 et les versions précédentes. Spécifiez la version de R que vous avez utilisée pour le processus aléatoire.
Il est souvent utile de consulter les exemples dans les fichiers d’aide des fonctions utilisées. En général, tout le code qui y est donné remplit les conditions requises pour un exemple reproductible minimal: les données sont fournies, le code minimal est fourni et tout est exécutable.
Dans la plupart des cas, cela peut être facilement fait en fournissant simplement un cadre de vecteur/données avec certaines valeurs. Ou vous pouvez utiliser l'un des jeux de données intégrés, fournis avec la plupart des packages.
Une liste complète des jeux de données intégrés peut être consultée avec library(help = "datasets")
. Il existe une brève description de chaque jeu de données et vous pouvez obtenir plus d'informations, par exemple avec ?mtcars
où 'mtcars' est l'un des jeux de données de la liste. D'autres packages peuvent contenir des ensembles de données supplémentaires.
Faire un vecteur est facile. Parfois, il est nécessaire d’ajouter de l’aléatoire à cela, et il existe toute une série de fonctions pour le rendre. sample()
peut randomiser un vecteur ou donner un vecteur aléatoire avec seulement quelques valeurs. letters
est un vecteur utile contenant l'alphabet. Ceci peut être utilisé pour créer des facteurs.
Quelques exemples:
x <- rnorm(10)
pour une distribution normale, x <- runif(10)
pour une distribution uniforme, ...x <- sample(1:10)
pour le vecteur 1:10 dans un ordre aléatoire.x <- sample(letters[1:4], 20, replace = TRUE)
Pour les matrices, on peut utiliser matrix()
, par exemple:
matrix(1:10, ncol = 2)
La création de trames de données peut être effectuée avec data.frame()
. Veillez à nommer les entrées dans le bloc de données et à ne pas le compliquer excessivement.
Un exemple :
set.seed(1)
Data <- data.frame(
X = sample(1:10),
Y = sample(c("yes", "no"), 10, replace = TRUE)
)
Pour certaines questions, des formats spécifiques peuvent être nécessaires. Pour ceux-ci, on peut utiliser l’une des fonctions as.someType
fournies: as.factor
, as.Date
, as.xts
, ... en combinaison avec les astuces de trames de vecteur et/ou de données .
Si vous avez des données qu'il serait trop difficile de construire avec ces astuces, vous pouvez toujours créer un sous-ensemble de vos données d'origine, en utilisant par exemple head()
, subset()
ou les index. Ensuite, utilisez par exemple. dput()
pour nous donner quelque chose qui peut être mis immédiatement dans R:
> 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")
Si votre trame de données a un facteur à plusieurs niveaux, la sortie dput
peut être difficile à manier car elle répertorie tous les niveaux de facteur possibles même s'ils ne sont pas présents dans le sous-ensemble de vos données. Pour résoudre ce problème, vous pouvez utiliser la fonction droplevels()
. Remarquez ci-dessous comment l’espèce est un facteur avec un seul niveau:
> 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")
Un autre inconvénient pour dput
est qu'il ne fonctionnera pas pour les objets data.table
clés ou pour les groupés tbl_df
(classe grouped_df
) à partir de dplyr
. Dans ces cas, vous pouvez reconvertir en trame de données normale avant le partage, dput(as.data.frame(my_data))
.
Dans le pire des cas, vous pouvez donner une représentation textuelle qui peut être lue à l'aide du paramètre text
de read.table
:
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)
Cela devrait être la partie la plus facile, mais ce n’est souvent pas le cas. Ce que vous ne devriez pas faire, c'est:
Ce que vous devriez faire, c'est:
library()
)unlink()
)op <- par(mfrow=c(1,2)) ...some code... par(op)
)Dans la plupart des cas, seule la version R et le système d'exploitation suffiront. Quand des conflits surviennent avec des paquets, donner le résultat de sessionInfo()
peut vraiment aider. Lorsque vous parlez de connexions à d'autres applications (que ce soit par le biais de ODBC ou de toute autre solution), vous devez également fournir les numéros de version de celles-ci et, si possible, également les informations nécessaires sur la configuration.
Si vous utilisez R dans , R Studio en utilisant rstudioapi::versionInfo()
peut être utile pour indiquer votre version de RStudio.
Si vous rencontrez un problème avec un paquet spécifique, vous pouvez vouloir fournir la version du paquet en donnant le résultat de packageVersion("name of the package")
.
(Voici mon conseil de Comment écrire un exemple reproductible . J'ai essayé de le rendre court mais agréable)
Si vous fournissez un exemple reproductible, vous aurez plus de chances d’obtenir une aide efficace concernant votre problème R. Un exemple reproductible permet à une autre personne de recréer votre problème en copiant et en collant du code R.
Pour rendre votre exemple reproductible, vous devez inclure quatre éléments: packages requis, données, code et description de votre environnement R.
Les packages doivent être chargés en haut du script, il est donc facile de voir ceux dont cet exemple a besoin.
Le moyen le plus simple d'inclure des données dans un courrier électronique ou une question de débordement de pile est d'utiliser dput()
pour générer le code R afin de le recréer. Par exemple, pour recréer le jeu de données mtcars
dans R, procédez comme suit:
dput(mtcars)
dans Rmtcars <-
puis collez.Passez un peu de temps à vous assurer que votre code est facile à lire pour les autres:
assurez-vous que vous avez utilisé des espaces et que vos noms de variables sont concis, mais informatifs
utiliser les commentaires pour indiquer où se situe votre problème
faites de votre mieux pour supprimer tout ce qui n'est pas lié au problème.
Plus votre code est court, plus il est facile à comprendre.
Incluez la sortie de sessionInfo()
dans un commentaire de votre code. Ceci résume votre environnement R et permet de vérifier facilement si vous utilisez un package obsolète.
Vous pouvez vérifier que vous avez bien créé un exemple reproductible en démarrant une nouvelle session R et en collant votre script au format.
Avant de mettre tout votre code dans un email, envisagez de le mettre Gist github . Votre code sera mis en évidence par la syntaxe, sans que vous ayez à vous soucier de quoi que ce soit qui puisse être endommagé par le système de messagerie.
Personnellement, je préfère les doublures. Quelque chose le long des lignes:
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)
La structure de données doit imiter l'idée du problème de l'auteur et non la structure exacte. J'apprécie vraiment quand les variables ne écrasent pas mes propres variables ou que dieu m'interdit, des fonctions (comme df
).
Alternativement, on pourrait couper quelques coins et pointer vers un ensemble de données préexistant, quelque chose comme:
library(vegan)
data(varespec)
ord <- metaMDS(varespec)
N'oubliez pas de mentionner les packages spéciaux que vous pourriez utiliser.
Si vous essayez de démontrer quelque chose sur des objets plus grands, vous pouvez essayer
my.df2 <- data.frame(a = sample(10e6), b = sample(letters, 10e6, replace = TRUE))
Si vous travaillez avec des données spatiales via le package raster
, vous pouvez générer des données aléatoires. La vignette du paquet contient de nombreux exemples, mais voici une petite pépite.
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)
Si vous avez besoin d'un objet géographique comme implémenté dans sp
, vous pouvez obtenir certains jeux de données via des fichiers externes (tels que le fichier de formes ESRI) dans des packages "spatiaux" (voir la vue Spatial dans les vues des tâches).
library(rgdal)
ogrDrivers()
dsn <- system.file("vectors", package = "rgdal")[1]
ogrListLayers(dsn)
ogrInfo(dsn=dsn, layer="cities")
cities <- readOGR(dsn=dsn, layer="cities")
Inspiré par cet article, j'utilise maintenant une fonction pratiquereproduce(<mydata>)
lorsque je dois publier sur StackOverflow.
Si myData
est le nom de votre objet à reproduire, exécutez ce qui suit dans R:
install.packages("devtools")
library(devtools)
source_url("https://raw.github.com/rsaporta/pubR/gitbranch/reproduce.R")
reproduce(myData)
Cette fonction est un wrapper intelligent pour dput
et effectue les opérations suivantes:
dput
objName <- ...
pour qu’il soit facile à copier + coller, mais ...# 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 est environ 100 x 102. Je veux échantillonner 10 lignes et quelques colonnes spécifiques
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==
Notez également que l'intégralité de la sortie se trouve dans une seule ligne de Nice, pas un paragraphe de lignes hachées. Cela facilite la lecture sur SO questions et facilite également la copie et le collage.
Vous pouvez maintenant spécifier le nombre de lignes de sortie de texte à utiliser (c.-à-d. Ce que vous allez coller dans StackOverflow). Utilisez l'argument lines.out=n
pour cela. Exemple:
reproduce(DF, cols=c(1:3, 17, 23), lines.out=7)
donne:
==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==
Voici un bon guide .
Le point le plus important est: Assurez-vous simplement de créer un petit morceau de code que nous pouvons exécuter pour voir quel est le problème . Une fonction utile pour cela est dput()
, mais si vous avez des données très volumineuses, vous pouvez créer un petit échantillon de données ou utiliser uniquement les 10 premières lignes environ.
EDIT:
Assurez-vous également que vous avez identifié le problème vous-même. L'exemple ne doit pas être un script R complet avec "Sur la ligne 200, il y a une erreur". Si vous utilisez les outils de débogage dans R (I love browser()
) et Google, vous devriez être en mesure d'identifier le problème et de reproduire un exemple trivial dans lequel la même chose ne va pas.
La liste de diffusion de R-help comporte un guide de publication , qui couvre à la fois les questions posées et les réponses, avec un exemple de génération de données:
Exemples: Parfois, il est utile de fournir un petit exemple que quelqu'un peut réellement exécuter. Par exemple:
Si j'ai une matrice x comme suit:
> 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
>
comment puis-je le transformer en un cadre de données avec 8 lignes, et trois colonnes nommées 'ligne', 'col' et 'valeur', qui ont les noms de dimension comme valeurs de 'ligne' et 'col', comme ceci:
> x.df
row col value
1 A x 1
...
(Pour laquelle la réponse pourrait être:
> 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")
)
Le mot petit est particulièrement important. Vous devriez viser un exemple reproductible minimal , ce qui signifie que les données et le code doivent être aussi simples que possible pour expliquer le problème.
EDIT: Joli code est plus facile à lire que le code laid. Utilisez un guide de style .
Depuis R.2.14 (je suppose), vous pouvez envoyer votre représentation textuelle de données directement à read.table
:
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
")
Parfois, le problème n'est vraiment pas reproductible avec des données plus petites, peu importe les efforts que vous déployez, ni avec les données synthétiques (bien qu'il soit utile de montrer comment vous avez produit des ensembles de données synthétiques non reproduisez le problème, car il exclut certaines hypothèses).
Si vous ne pouvez pas résoudre l'un de ces problèmes, vous devrez probablement faire appel à un consultant pour résoudre votre problème ...
edit : Deux questions SO utiles pour l'anonymisation/le brouillage:
Les réponses à ce jour sont évidemment excellentes pour la partie reproductibilité. Il s'agit simplement de préciser qu'un exemple reproductible ne peut et ne doit pas être le seul élément d'une question. N'oubliez pas d'expliquer ce à quoi vous voulez ressembler et les contours de votre problème, pas simplement comment vous avez essayé d'y arriver jusqu'à présent. Le code ne suffit pas; vous avez aussi besoin de mots.
Voici un exemple reproductible de ce qu'il faut éviter (tiré d'un exemple réel, les noms ont été modifiés pour protéger l'innocent):
Ce qui suit est un exemple de données et une partie de la fonction avec laquelle j'ai des problèmes.
code
code
code
code
code (40 or so lines of it)
Comment puis-je atteindre cet objectif ?
J'ai un moyen très facile et efficace de faire un exemple R qui n'a pas été mentionné ci-dessus. Vous pouvez définir votre structure en premier lieu. Par exemple,
mydata <- data.frame(a=character(0), b=numeric(0), c=numeric(0), d=numeric(0))
>fix(mydata)
Ensuite, vous pouvez saisir vos données manuellement. Ceci est efficace pour les petits exemples plutôt que pour les grands.
Pour créer rapidement un dput
de vos données, vous pouvez simplement copier (un morceau de) les données dans votre presse-papiers et exécuter ce qui suit dans R:
pour les données dans Excel:
dput(read.table("clipboard",sep="\t",header=TRUE))
pour les données dans un fichier txt:
dput(read.table("clipboard",sep="",header=TRUE))
Vous pouvez modifier la sep
dans cette dernière si nécessaire. Cela ne fonctionnera que si vos données sont dans le presse papier bien sûr.
Votre objectif principal dans l’élaboration de vos questions devrait être de permettre aux lecteurs de comprendre et de reproduire votre problème aussi facilement que possible sur leurs systèmes. Faire cela:
Cela prend un peu de travail mais semble être un compromis juste puisque vous demandez aux autres de faire le travail pour vous.
La meilleure option est de loin de s'appuyer sur des jeux de données intégrés. Cela rend très facile pour les autres de travailler sur votre problème. Tapez data()
à l'invite R pour voir quelles données sont disponibles. Quelques exemples classiques:
iris
mtcars
ggplot2::diamonds
(paquet externe, mais presque tout le monde le possède)Voir ceci SO QA pour savoir comment trouver des ensembles de données adaptés à votre problème.
Si vous pouvez reformuler votre problème en utilisant les jeux de données intégrés, vous aurez beaucoup plus de chances d'obtenir de bonnes réponses (et des votes positifs).
Si votre problème est très spécifique à un type de données qui n'est pas représenté dans les ensembles de données existants, indiquez le code R qui génère le plus petit jeu de données possible . que votre problème se manifeste. Par exemple
set.seed(1) # important to make random data reproducible
myData <- data.frame(a=sample(letters[1:5], 20, rep=T), b=runif(20))
Maintenant, quelqu'un qui essaie de répondre à ma question peut copier/coller ces deux lignes et commencer à travailler sur le problème immédiatement.
En dernier recours , vous pouvez utiliser dput
pour transformer un objet de données en code R (par exemple, dput(myData)
). Je dis en "dernier recours" car la sortie de dput
est souvent assez lourde, ennuyeuse à copier-coller et obscurcit le reste de votre question.
Quelqu'un a déjà dit:
Une image de la sortie attendue vaut 1000 mots
- une personne très sage
Si vous pouvez ajouter quelque chose comme "Je m'attendais à ce résultat":
cyl mean.hp
1: 6 122.28571
2: 4 82.63636
3: 8 209.21429
à votre question, les gens sont beaucoup plus susceptibles de comprendre rapidement ce que vous essayez de faire. Si le résultat escompté est large et difficile à manier, vous n'avez probablement pas suffisamment réfléchi à la façon de simplifier votre problème (voir ci-après).
La principale chose à faire est de simplifier votre problème autant que possible avant de poser votre question. Recadrer le problème pour travailler avec les jeux de données intégrés aidera beaucoup à cet égard. Vous constaterez aussi souvent qu'en procédant simplement à la simplification, vous pourrez résoudre votre propre problème.
Voici quelques exemples de bonnes questions:
Dans les deux cas, les problèmes des utilisateurs ne sont certainement pas liés aux exemples simples qu’ils fournissent. Au lieu de cela, ils ont résumé la nature de leur problème et l'ont appliqué à un simple ensemble de données pour poser leur question.
Cette réponse se concentre sur ce que je pense être la meilleure pratique: utiliser des ensembles de données intégrés et fournir ce que vous attendez comme résultat sous une forme minimale. Les réponses les plus importantes se concentrent sur d'autres aspects. Je ne m'attends pas à ce que cette réponse prenne de l'importance. c'est ici uniquement pour que je puisse y faire un lien dans les commentaires aux questions de débutant.
Le code reproductible est la clé pour obtenir de l'aide. Cependant, de nombreux utilisateurs peuvent être sceptiques quant au collage, même partiel. Par exemple, ils pourraient utiliser des données sensibles ou des données originales collectées pour être utilisées dans un document de recherche. Pour une raison quelconque, je pensais que ce serait bien d’avoir une fonction pratique pour "déformer" mes données avant de les coller publiquement. La fonction anonymize
du paquet SciencesPo
est très ridicule, mais pour moi, elle fonctionne bien avec la fonction dput
.
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
Puis je anonymise:
> 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
On peut également vouloir échantillonner quelques variables au lieu de l’ensemble des données avant d’appliquer l’anonymisation et la commande dput.
# 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
Vous avez souvent besoin de données pour un exemple, cependant, vous ne voulez pas publier vos données exactes. Pour utiliser un fichier data.frame existant dans une bibliothèque établie, utilisez la commande data pour l'importer.
par exemple.,
data(mtcars)
et ensuite faire le problème
names(mtcars)
your problem demostrated on the mtcars data set
Je développe le package wakefield pour répondre à ce besoin de partager rapidement des données reproductibles, parfois dput
fonctionne bien pour des ensembles de données plus petits, mais bon nombre des problèmes que nous traitons sont beaucoup plus vastes. Le partage d'un ensemble de données aussi volumineux via dput
n'est pas pratique.
À propos de:
wakefield permet à l'utilisateur de partager un code minimal pour reproduire les données. L'utilisateur définit n
(nombre de lignes) et spécifie un nombre quelconque de fonctions variables prédéfinies (il en existe actuellement 70) qui imitent des données réelles si (éléments tels que le sexe, l'âge, le revenu, etc.)
Installation:
Actuellement (2015-06-11), wakefield est un paquet GitHub mais ira à CRAN éventuellement après la rédaction des tests unitaires. Pour installer rapidement, utilisez:
if (!require("pacman")) install.packages("pacman")
pacman::p_load_gh("trinker/wakefield")
Exemple:
Voici un exemple:
r_data_frame(
n = 500,
id,
race,
age,
sex,
hour,
iq,
height,
died
)
Cela produit:
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
.. ... ... ... ... ... ... ... ...
Si vous avez une ou plusieurs variables factor
dans vos données que vous souhaitez rendre reproductibles avec dput(head(mydata))
, pensez à y ajouter droplevels
, de sorte que les niveaux de facteurs non présents dans le jeu de données minimisé ne sont pas inclus dans votre sortie dput
afin de rendre l'exemple minimal:
dput(droplevels(head(mydata)))
Je me demande si un lien http://old.r-fiddle.org/ pourrait être un moyen très judicieux de partager un problème. Il reçoit un identifiant unique et on pourrait même penser à l’intégrer dans SO.
Veuillez ne pas coller vos sorties de console comme ceci:
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")
)
Nous ne pouvons pas copier-coller directement.
Pour que les questions et réponses puissent être reproduites correctement, essayez de supprimer +
& >
avant de le publier et mettez #
pour les sorties et les commentaires comme celui-ci:
#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")
Une dernière chose, si vous avez utilisé une fonction de certains paquetages, mentionnez cette bibliothèque.
En dehors de toutes les réponses ci-dessus que j'ai trouvées très intéressantes, cela peut parfois s'avérer très simple, car il est discuté ici: - COMMENT FAIRE UN EXEMPLE DE REPRODUCTION MINIMAL POUR OBTENIR DE L'AIDE AVEC R
Il existe de nombreuses façons de créer un vecteur aléatoire Créer un vecteur de 100 nombres avec des valeurs aléatoires dans R arrondies à 2 décimales ou une matrice aléatoire dans R
mydf1<- matrix(rnorm(20),nrow=20,ncol=5)
Notez qu'il est parfois très difficile de partager une donnée donnée pour diverses raisons, telles que la dimension, etc. Cependant, toutes les réponses ci-dessus sont excellentes et très importantes à penser et à utiliser lorsque vous souhaitez créer un exemple de données reproductible. Mais notez que pour rendre des données aussi représentatives que l'original (au cas où l'OP ne puisse pas partager les données d'origine), il est bon d'ajouter des informations avec l'exemple de données tel que (si nous appelons les données mydf1)
class(mydf1)
# this shows the type of the data you have
dim(mydf1)
# this shows the dimension of your data
De plus, il faut connaître le type, la longueur et les attributs d’une donnée qui peut être Structure de données
#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))
Vous pouvez le faire en utilisant reprex .
Comme mt1022 a noté , "... un bon paquet pour produire un exemple reproductible minimal est " reprex " de tidyverse ".
Selon Tidyverse :
Le but de "reprex" est d’empaqueter votre code problématique de manière à ce que d’autres personnes puissent l’exécuter et ressentir votre douleur.
Un exemple est donné sur le site tidyverse .
library(reprex)
y <- 1:4
mean(y)
reprex()
Je pense que c'est le moyen le plus simple de créer un exemple reproductible.
Voici certaines de mes suggestions:
dput
pour que les autres puissent vous aider plus facilement.install.package()
sauf si cela est vraiment nécessaire, les gens comprendront si vous utilisez simplement require
ou library
Essayez d'être concis,
Tout cela fait partie d'un exemple reproductible.
C'est une bonne idée d'utiliser les fonctions du paquetage testthat
pour montrer ce que vous attendez. Ainsi, d'autres personnes peuvent modifier votre code jusqu'à ce qu'il s'exécute sans erreur. Cela facilite le travail de ceux qui souhaitent vous aider, car cela signifie qu'ils n'ont pas à déchiffrer votre description textuelle. Par exemple
library(testthat)
# code defining x and y
if (y >= 10) {
expect_equal(x, 1.23)
} else {
expect_equal(x, 3.21)
}
est plus clair que "je pense que x s'avérerait être 1,23 pour y égal ou supérieur à 10, et 3,21 sinon, mais je n'ai eu aucun résultat". Même dans cet exemple idiot, je pense que le code est plus clair que les mots. L'utilisation de testthat
permet à votre assistant de se concentrer sur le code, ce qui lui permet de gagner du temps et de disposer du moyen de savoir qu'il a résolu votre problème avant de le publier.