Comment faire un grand R exemple reproductible

Lorsqu'on discute de performance avec des collègues, qu'on enseigne, qu'on envoie un rapport de bogue ou qu'on cherche des conseils sur les listes de diffusion et ici sur le débordement de la pile, un exemple reproductible est souvent demandé et toujours utile.

Quels sont vos conseils pour créer un excellent exemple? Comment coller les structures de données de dans un format de texte? Quels autres renseignements devez-vous inclure?

sont là autres astuces en plus d'utiliser dput() , dump() ou structure() ? Quand devez-vous inclure les énoncés library() ou require() ? Quels mots réservés doit-on éviter, en plus de c , df , data , etc.?

Comment faire un grand exemple reproductible?

2445
demandé sur Hack-R 2011-05-11 15:12:02

23 réponses

un exemple minimal reproductible se compose des éléments suivants:

  • un ensemble minimal de données, nécessaire pour reproduire l'erreur
  • les minimes praticable code nécessaire pour reproduire l'erreur, qui peut être exécuté sur le jeu de données.
  • les informations nécessaires sur les emballages, la version R, et le système d'exécution.
  • dans le cas de l'aléatoire procédés, une graine (fixée par set.seed() ) pour reproductibilité

en Regardant les exemples dans les fichiers d'aide des fonctions est souvent utile. En général, tout le code qui y est donné répond aux exigences d'un exemple de reproductibilité minimale: les données sont fournies, le code minimal est fourni, et tout est exécutable.

production d'un ensemble minimal de données

pour la plupart des cas, cela peut être facilement fait en fournissant une base de données vectorielle avec quelques valeurs. Ou vous pouvez utiliser l'un des ensembles de données, qui sont fournis avec la plupart des paquets.

Une liste complète des ensembles de données intégrés peut être vue avec library(help = "datasets") . Il y a une brève description de chaque ensemble de données et plus d'informations peuvent être obtenues par exemple avec ?mtcars où "mtcars" est l'un des ensembles de données dans la liste. D'autres paquets peuvent contenir des ensembles de données supplémentaires.

fabriquer un vecteur est facile. Il est parfois nécessaire d'ajouter un peu de hasard, et il y a un certain nombre de fonctions pour faire que. sample() peut randomiser un vecteur, ou donner un vecteur aléatoire avec seulement quelques valeurs. letters est un vecteur utile contenant l'alphabet. Cela peut être utilisé pour faire des facteurs.

quelques exemples:

  • valeurs aléatoires : x <- rnorm(10) pour une distribution normale, x <- runif(10) pour une distribution uniforme, ...
  • une permutation de quelques valeurs: x <- sample(1:10) pour vecteur 1:10 dans l'ordre aléatoire.
  • un facteur 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 cadres de données peut être effectuée en utilisant data.frame() . Il faut veiller à nommer les entrées dans la base de données et à ne pas la rendre trop compliquée.

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 n'importe laquelle des fonctions as.someType fournies: as.factor , as.Date , as.xts , ... Ceux-ci en combinaison avec le vecteur et/ou des astuces de base de données.

copier vos données

si vous avez des données qui seraient trop difficiles à construire en utilisant ces conseils, alors vous pouvez toujours faire un sous-ensemble de vos données originales, en utilisant eg head() , subset() ou les indices. Ensuite, utilisez par exemple. dput() pour nous donner quelque chose qui peut être mis dans R immédiatement:

> 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 base de données a un facteur avec de nombreux niveaux, la sortie dput peut être lourde parce qu'elle énumérera encore tous les niveaux de facteur possibles même si elles ne sont pas présentes 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")

une autre mise en garde pour dput est qu'il ne fonctionnera pas pour les objets à clé data.table ou pour groupés tbl_df (classe grouped_df ) de dplyr . Dans ces cas, vous pouvez convertir de nouveau à une base de données régulière 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 en utilisant le 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)

production de code minimal

cela devrait être la partie facile mais souvent ne l'est pas. Ce que vous ne devriez pas faire, c'est:

  • ajoutez toutes sortes de conversions de données. Assurez-vous que les données fournies sont déjà dans le format correct (à moins que ce soit le problème bien sûr)
  • copier-coller une fonction entière/morceau de code qui donne une erreur. Tout d'abord, essayez de trouver quelles lignes résultent exactement de l'erreur. Plus souvent qu'autrement, vous aurez trouver quel est le problème vous-même.

Ce que vous devez faire, c'est:

  • ajouter quels colis doivent être utilisés si vous utilisez un (en utilisant library() )
  • si vous ouvrez des connexions ou créez des fichiers, ajoutez du code pour les fermer ou supprimez les fichiers (en utilisant unlink() )
  • si vous changez d'option, assurez-vous que le code contient une instruction pour les ramener aux options originales. (par exemple op <- par(mfrow=c(1,2)) ...some code... par(op) )
  • test lancez votre code dans une nouvelle session R vide pour vous assurer que le code est exécutable. Les gens devraient pouvoir simplement copier-coller vos données et votre code dans la console et obtenir exactement la même chose que vous avez.

donner des informations supplémentaires

dans la plupart des cas, seule la version R et le système d'exploitation suffisent. Lorsque des conflits apparaissent avec les paquets, donner la sortie de sessionInfo() peut vraiment aider. Lorsqu'on parle de connexions à d'autres applications (que ce soit via ODBC ou autre), il faut également fournir les numéros de version de celles-ci, et si possible aussi les informations nécessaires sur la configuration.

si vous utilisez R dans R Studio en utilisant rstudioapi::versionInfo() peut être utile pour signaler votre version RStudio.

Si vous avez un problème avec un paquet, vous souhaiterez peut-être fournir la version du paquet par donnant la sortie de packageVersion("name of the package") .

1498
répondu Joris Meys 2018-08-08 09:18:55

(Voici mon conseil de Comment écrire un exemple reproductible . J'ai essayé de faire court mais doux)

Comment écrire un exemple reproductible.

vous êtes le plus susceptible d'obtenir une bonne aide avec votre problème R Si vous fournissez un exemple reproductible. Un exemple reproductible permet à quelqu'un d'autre de recréer votre problème en copiant et collant simplement le code R.

Il y a quatre choses que vous devez incluez pour rendre votre exemple reproductible: les paquets requis, les données, le code et une description de votre environnement.

  • les paquets doivent être chargés en haut du script, il est donc facile de voyez ceux dont l'exemple a besoin.

  • la façon la plus facile d'inclure données dans un courriel ou une question de débordement de pile est d'utiliser dput() pour générer la R code pour le recréer. Par exemple, pour recréer L'ensemble de données mtcars dans R, Je ferais les pas suivants:

    1. Exécuter dput(mtcars) R
    2. copier la sortie
    3. dans mon script reproductible, tapez mtcars <- puis collez.
  • Passez un peu de temps à vous assurer que votre code est facile pour les autres lire:

    • assurez-vous que vous avez utilisé des espaces et vos noms de variables sont concis, mais informatif

    • utilisez les commentaires pour indiquer où se trouve votre problème

    • faites de votre mieux pour enlever 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 dans votre code. Ceci résume votre R environnement et rend facile de vérifier si vous utilisez un paquet.

vous pouvez vérifier que vous avez réellement fait un exemple reproductible en démarrant une nouvelle session R et en collant votre script.

avant de mettre tout votre code dans un e-mail, pensez à le mettre sur Gist github . Il donnera à votre code la mise en évidence de la syntaxe agréable, et vous n'avez pas à vous soucier de quoi que ce soit de se mutiler par le système de courrier électronique.

526
répondu hadley 2018-03-20 04:02:59

personnellement, je préfère les doublures "un". Quelque chose dans le genre:

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 des données doit imiter l'idée du problème de l'auteur et non la structure mot à mot exacte. J'apprécie vraiment quand les variables n'écrasent pas mes propres variables ou Dieu nous en préserve, les fonctions (comme df ).

autrement, 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 paquets 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 paquet raster , vous pouvez générer des données aléatoires. Beaucoup d'exemples peuvent être trouvés dans le paquet de la vignette, 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 ensembles de données via des fichiers externes (comme ESRI shapefile) dans des paquets" spatiaux " (voir la vue spatiale dans les vues de 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")
266
répondu Roman Luštrik 2017-10-18 07:42:33

inspiré par ce même post, j'utilise maintenant une fonction pratique

reproduce(<mydata>) quand j'ai besoin de poster pour StackOverflow.


QUICK INSTRUCTIONS

si myData est le nom de votre objet à reproduire, exécuter ce qui suit dans R:

install.packages("devtools")
library(devtools)
source_url("https://raw.github.com/rsaporta/pubR/gitbranch/reproduce.R")

reproduce(myData)

détails:

cette fonction est un enveloppeur intelligent pour dput et fait ce qui suit:

  • échantillonne automatiquement un grand ensemble de données (basé sur la taille et la classe. La taille de l'échantillon peut être ajustée)
  • crée une dput sortie
  • vous permet de spécifier quelles colonnes exporter
  • ajoute à l'avant de celui-ci objName <- ... de sorte qu'il peut être facilement copier+coller, mais...
  • si vous travaillez sur un mac, la sortie est automatiquement copiée sur le presse-papier, de sorte que vous pouvez simplement l'exécuter et ensuite coller à votre question.

la source est disponible ici:


exemple:

# 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 d'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. 

donne la sortie suivante:

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==

remarquez aussi que la totalité de la sortie est dans une belle ligne simple, longue, pas un grand paragraphe de lignes hachées. Cela le rend plus facile à lire sur les messages de questions ainsi que plus facile à copier + coller.


Mise À Jour Octobre 2013:

vous pouvez maintenant spécifier combien de lignes de sortie de texte va prendre (c'est-à-dire, ce que vous va 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==
247
répondu Ricardo Saporta 2018-03-20 03:59:30

voici un bon guide:

http://www.r-bloggers.com/three-tips-for-posting-good-questions-to-r-help-and-stack-overflow /

Mais le plus important: assurez-vous que vous faites 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 volumineux, vous voudrez peut-être faire un petit échantillon de données ou seulement les 10 premières lignes.

EDIT:

assurez-vous également que vous avez identifié où le problème est vous-même. L'exemple ne doit pas être un script R entier avec "on line 200 there is an error". Si vous utilisez les outils de débogage de R (j'aime browser() ) et google, vous devriez être en mesure d'identifier vraiment où le problème est et de reproduire un exemple trivial dans lequel la même chose va mal.

172
répondu Sacha Epskamp 2011-05-11 11:28:17

la liste de diffusion R-help contient un guide d'affichage qui couvre à la fois les questions posées et les réponses données, y compris un exemple de génération de données:

exemples: parfois, il aide à un petit exemple d'une personne qui peut s'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 une base de données avec 8 lignes et trois colonnes nommées 'ligne', 'col', et 'valeur', qui ont les noms de dimension comme les valeurs de 'row' et 'col', comme ceci:

  > x.df
     row col value
  1    A   x      1

...

(Dont 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 small est particulièrement important. Vous devriez viser pour un "1519280920 exemple "minimal reproductible, ce qui signifie que les données et le code doivent être aussi simples que possible pour expliquer le problème.

EDIT: Pretty code est plus facile à lire que ugly code. Utilisez un guide de style .

146
répondu Richie Cotton 2011-05-11 14:05:03

Depuis La R. 2.14 (je suppose) vous pouvez alimenter votre représentation de texte de données directement pour lire.tableau:

df <- read.table(header=T, 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
") 
141
répondu Paolo 2012-06-29 08:32:04

parfois, le problème n'est vraiment pas reproductible avec un petit morceau de données, peu importe comment vous essayez, et ne se produit pas avec des données synthétiques (bien qu'il soit utile de montrer comment vous avez produit des ensembles de données synthétiques qui pas reproduire le problème, parce qu'il écarte certaines hypothèses).

  • afficher les données sur le web quelque part et fournir une URL peut être nécessaire.
  • Si les données ne peuvent pas être mis à la disposition du grand public mais pouvant être partagé, vous pourrez alors peut-être offrir de l'envoyer par courriel aux parties intéressées (bien que cela réduira le nombre de personnes qui se donneront la peine de travailler dessus).
  • Je n'ai pas réellement vu Cela fait, parce que les gens qui ne peuvent pas diffuser leurs données sont sensibles à la diffusion de toute forme, mais il semblerait plausible que dans certains cas, on pourrait encore poster des données si elles étaient suffisamment anonymisées/brouillées/légèrement corrompues dans d'une certaine façon.

si vous ne pouvez pas faire l'un ou l'autre de ceux-ci, alors vous avez probablement besoin d'engager un consultant pour résoudre votre problème ...

edit : deux questions utiles pour l'anonymisation/ brouillage:

131
répondu Ben Bolker 2017-05-23 11:47:32

les réponses jusqu'à présent 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 la seule composante d'une question. N'oubliez pas d'expliquer ce que vous voulez qu'il ressemble et les contours de votre problème, et pas seulement la façon dont vous avez essayé d'obtenir jusqu'à présent. Le Code ne suffit pas; il faut aussi des mots.

voici un exemple reproductible de ce qu'il faut éviter de faire (tiré d'un exemple réel, les noms changés pour protéger les innocents):


ce qui suit est un échantillon 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 y parvenir ?


119
répondu Ari B. Friedman 2012-07-09 16:35:28

pour créer rapidement un dput de vos données vous pouvez simplement copier (un morceau de) les données à votre bloc-notes et exécuter ce qui suit dans R:

pour les données en 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 changer le sep dans ce dernier si nécessaire. Cela ne fonctionnera que si vos données dans le presse-papiers de cours.

103
répondu JT85 2013-04-10 15:03:06

j'ai un moyen facile et efficace pour faire un R exemple qui n'a pas été mentionné ci-dessus. Vous pouvez d'abord définir votre structure. Par exemple,

mydata <- data.frame(a=character(0), b=numeric(0),  c=numeric(0), d=numeric(0))

>fix(mydata)

When you execute 'fix' command, you will get this pop-up box

alors vous pouvez entrer vos données manuellement. C'est efficace pour les petits exemples plutôt que des gros.

99
répondu jasmine_007 2018-08-19 17:19:33

code reproductible est la clé pour obtenir de l'aide. Cependant, il ya beaucoup d'utilisateurs qui pourraient être sceptiques de coller encore une partie de leurs données. Par exemple, ils pourraient travailler avec des données sensibles ou sur des données originales recueillies pour les utiliser dans un document de recherche. Pour n'importe quelle raison, j'ai pensé qu'il serait agréable 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 stupide, mais pour moi elle fonctionne bien avec dput de la fonction.

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

alors je l'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 aussi vouloir échantillonner quelques variables au lieu des données complètes avant d'appliquer la commande anonymisation et 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
97
répondu daniel 2016-02-09 10:37:51

lignes directrices:


votre principal objectif dans l'élaboration de vos questions devrait être de rendre aussi facile que possible pour les lecteurs de comprendre et de reproduire votre problème sur leurs systèmes. Pour ce faire:

  1. Fournir des données d'entrée
  2. résultats escomptés
  3. Expliquez votre problème succinctement
    • si vous avez plus de 20 lignes de texte + code vous pouvez probablement revenir en arrière et simplifier
    • simplifiez votre code autant que possible tout en préservant le problème/l'erreur

cela demande du travail mais semble être un compromis équitable puisque vous demandez à d'autres de faire du travail pour vous.

Fournissant Des Données:


ensembles de données intégrés

La meilleure option par far est de s'appuyer sur des ensembles 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 l'a)

voir ce SO QA comment trouver des ensembles de données adaptée à votre problème.

si vous êtes en mesure de reformuler votre problème pour utiliser les ensembles de données intégrés, vous êtes beaucoup plus susceptible d'obtenir de bonnes réponses (et des notes positives).

Auto-Généré De Données

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, alors fournir le code R qui génère le plus petit possible ensemble de données sur lesquelles 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.

dput

en tant que dernier recours , vous pouvez utiliser dput pour transformer un objet de données en code R (par exemple dput(myData) ). Je dis comme un "dernier recours" parce que la production de dput est souvent assez lourd, ennuyeux à copier-coller, et obscurci le reste de votre question.

Résultats Escomptés:


Quelqu'un a dit:

une image de la production prévue vaut 1000 mots

très sage

Si vous pouvez ajouter quelque chose comme "je m'attendais à obtenir 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 votre résultat attendu est grand et lourd, alors vous n'avez probablement pas assez pensé comment simplifier votre problème (voir le point suivant).

Expliquer Votre Problème Succinctement


La principale chose à faire est de simplifier votre problème autant que possible avant de poser votre question. Reformuler le problème pour travailler avec les ensembles de données intégrés seront très utiles à cet égard. Vous constaterez aussi souvent qu'en passant par le processus de simplification, vous répondrez à votre propre problème.

voici quelques exemples de bonnes questions:

Dans les deux cas, les problèmes de l'utilisateur sont presque certainement pas avec les simples exemples qu'ils fournissent. Ils ont plutôt résumé la nature de leur problème et l'ont appliqué à un ensemble simple de données pour poser leur question.

Pourquoi Une Autre Réponse À Cette 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 n'ai pas attendez - vous à ce que cette réponse à monter à n'importe quelle proéminence; ceci est ici seulement pour que je puisse le lier dans des commentaires à des questions débutants.

97
répondu BrodieG 2017-10-18 07:35:50

Souvent, vous avez besoin de certaines données pour un exemple, cependant, vous ne voulez pas afficher vos données exactes. Pour utiliser certaines données existantes.frame dans la bibliothèque établie, utilisez la commande data pour l'importer.

par exemple,

data(mtcars)

et puis faire le problème

names(mtcars)
your problem demostrated on the mtcars data set
89
répondu userJT 2013-02-22 15:29:33

si vous avez un grand ensemble de données qui ne peut pas être facilement mis dans le script en utilisant dput() , postez vos données sur pastebin et chargez-les en utilisant read.table :

d <- read.table("http://pastebin.com/raw.php?i=m1ZJuKLH")

inspiré par @Henrik .

81
répondu TMS 2017-05-23 12:10:46

je développe le wakefield package pour répondre à ce besoin de partager rapidement des données reproductibles, parfois dput fonctionne très bien pour les ensembles de données plus petits, mais beaucoup des problèmes que nous traitons sont beaucoup plus grands, le partage d'un ensemble de données aussi grand via dput est impraticable.

à Propos de:

wakefield permet à l'utilisateur de partager un code minimal pour reproduire des données. L'utilisateur définit n (nombre de lignes) et spécifie n'importe quel nombre de fonctions variables préétablies (il y en a actuellement 70) qui imitent des données réelles si (des choses comme le sexe, l'âge, le revenu, etc.)

Installation:

actuellement (2015-06-11), wakefield est un paquet GitHub, mais il finira par aller au CRAN après les 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
)

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
.. ...   ... ...    ...      ... ...    ...   ...
77
répondu Tyler Rinker 2015-06-11 13:57:38

si vous avez une ou plusieurs variables factor dans vos données que vous voulez rendre reproductibles avec dput(head(mydata)) , envisager d'ajouter droplevels à elle, de sorte que les niveaux de facteurs qui ne sont pas présents dans l'ensemble de données minimisées ne sont pas inclus dans votre dput sortie, afin de faire l'exemple minime :

dput(droplevels(head(mydata)))
65
répondu docendo discimus 2015-01-09 15:35:32

je me demande si un http://old.r-fiddle.org/ lien pourrait être une très belle façon de partager un problème. Il reçoit un ID unique comme et on pourrait même penser à l'intégrer dans SO.

53
répondu CMichael 2018-09-09 19:24:31

S'il vous plaît ne collez pas les sorties de votre 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 les réponses soient correctement reproductibles, essayez de supprimer + et > avant de les afficher et mettez # pour les extrants et les commentaires 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")

encore une chose, si vous avez utilisé une fonction de certains paquets, mentionnez cette bibliothèque.

39
répondu user2100721 2018-08-19 17:17:58

mis à part toutes les réponses ci-dessus que j'ai trouvé très intéressant, il pourrait parfois être très facile comme il est discuté ici :- comment faire un exemple reproductible MINIMAL pour obtenir de l'aide avec R

il y a plusieurs façons de créer un vecteur aléatoire créer un vecteur de 100 nombres avec des valeurs aléatoires en R arrondies à 2 décimales ou une matrice aléatoire en r

mydf1<- matrix(rnorm(20),nrow=20,ncol=5)

notez que parfois il est très difficile partager une donnée pour diverses raisons telles que la dimension, etc. Cependant, toutes les réponses ci-dessus sont grandes et très importantes pour penser et utiliser quand on veut faire un exemple de données reproductibles. Mais notez que pour rendre une donnée aussi représentative que l'original (dans le cas où L'OP ne peut pas partager les données originales), il est bon d'ajouter quelques informations avec l'exemple de données comme (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 attributs d'une donnée qui peut être structures 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))
26
répondu 5 revs, 2 users 84%user5947301 2018-03-20 03:57:42

voici quelques-unes de mes suggestions:

  • Essayez d'utiliser la valeur par défaut R ensembles de données
  • si vous avez votre propre ensemble de données, incluez-les avec dput , pour que d'autres puissent vous aider plus facilement
  • N'utilisez pas install.package() sauf si c'est vraiment nécessaire, les gens comprendront si vous utilisez simplement require ou library
  • Essayer d'être concis,

    • ont certains dataset
    • essayez de décrire la sortie dont vous avez besoin aussi simplement que possible
    • Faites-le vous-même avant de vous poser la question
  • il est facile de télécharger une image, donc télécharger des parcelles si vous avez""
  • incluez aussi toutes les erreurs que vous pourriez avoir

tous ces éléments font partie d'un exemple reproductible.

22
répondu TheRimalaya 2016-04-11 06:18:45

vous pouvez le faire en utilisant reprex .

Comme mt1022 noté , "... bon paquet pour produire minimum, reproductible exemple est "reprex " de tidyverse ".

selon Tidyverse :

le but de "reprex" est d'empaqueter votre code problématique d'une manière telle que d'autres personnes peuvent exécuter et de sentir votre douleur.

un exemple est donné sur le site tidyverse .

library(reprex)
y <- 1:4
mean(y)
reprex() 

je pense que c'est la façon la plus simple pour créer un exemple reproductible.

22
répondu andrii 2017-08-19 05:56:55

c'est une bonne idée d'utiliser les fonctions du paquet testthat pour montrer ce que vous attendez de se produire. Ainsi, d'autres personnes peuvent modifier votre code jusqu'à ce qu'il s'exécute sans erreur. Cela facilite la tâche de ceux qui voudraient vous aider, parce que cela signifie qu'ils n'ont pas à décoder 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 serait arrivé à 1,23 pour y égale ou supérieure à 10, et 3.21 autrement, mais je n'ai eu ni le résultat". Même dans cet exemple stupide, je pense que le code est plus clair que les mots. L'utilisation de testthat permet à votre helper de se concentrer sur le code, ce qui lui permet de gagner du temps, et il leur permet de savoir qu'ils ont résolu votre problème, avant de le poster

13
répondu dank 2017-04-04 21:08:35