कैसे एक महान आर प्रतिलिपि प्रस्तुत करने योग्य उदाहरण बनाने के लिए

May 11 2011

सहकर्मियों के साथ प्रदर्शन पर चर्चा, शिक्षण, बग रिपोर्ट भेजना या मेलिंग सूचियों पर मार्गदर्शन के लिए खोज करना और यहां स्टैक ओवरफ्लो पर, एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण अक्सर पूछा जाता है और हमेशा मददगार होता है।

एक उत्कृष्ट उदाहरण बनाने के लिए आपके सुझाव क्या हैं? आप टेक्स्ट फॉर्मेट में r से डेटा स्ट्रक्चर कैसे पेस्ट करते हैं ? आपको और कौन सी जानकारी शामिल करनी चाहिए?

वहाँ का उपयोग करने के अलावा अन्य चालें हैं dput(), dump()या structure()? आपको कब शामिल करना चाहिए library()या require()कथन? कौन सा शब्द आरक्षित चाहिए एक से बचने के अलावा करने के लिए c, df, data, आदि?

एक महान आर प्रजनन योग्य उदाहरण कैसे बनता है?

जवाब

1756 JorisMeys May 11 2011 at 18:40

एक न्यूनतम प्रजनन योग्य उदाहरण में निम्नलिखित वस्तुएं शामिल हैं:

  • समस्या को प्रदर्शित करने के लिए आवश्यक न्यूनतम डेटासेट
  • त्रुटि को पुन: उत्पन्न करने के लिए आवश्यक न्यूनतम रननीय कोड, जिसे दिए गए डेटासेट पर चलाया जा सकता है
  • उपयोग किए गए पैकेज, आर संस्करण, और सिस्टम पर आवश्यक जानकारी इसे चलाया जाता है।
  • यादृच्छिक प्रक्रियाओं के मामले में, set.seed()प्रजनन के लिए एक बीज (सेट द्वारा ) 1

अच्छे न्यूनतम प्रजनन योग्य उदाहरणों के उदाहरणों के लिए , आपके द्वारा उपयोग किए जा रहे फ़ंक्शन की सहायता फ़ाइलों को देखें। सामान्य तौर पर, वहां दिए गए सभी कोड न्यूनतम प्रतिलिपि प्रस्तुत करने योग्य उदाहरण की आवश्यकताओं को पूरा करते हैं: डेटा प्रदान किया जाता है, न्यूनतम कोड प्रदान किया जाता है, और सब कुछ चल रहा है। ढेर सारे अपवॉट्स के साथ स्टैक ओवरफ्लो पर भी प्रश्न देखें।

न्यूनतम डेटासेट का उत्पादन करना

ज्यादातर मामलों के लिए, यह केवल कुछ मूल्यों के साथ एक वेक्टर / डेटा फ्रेम प्रदान करके आसानी से किया जा सकता है। या आप बिल्ट-इन डेटासेट्स में से एक का उपयोग कर सकते हैं, जो अधिकांश पैकेजों के साथ प्रदान किए जाते हैं।
अंतर्निहित डेटासेट की एक व्यापक सूची के साथ देखा जा सकता है library(help = "datasets")। प्रत्येक डेटासेट के लिए एक संक्षिप्त विवरण होता है और उदाहरण के लिए अधिक जानकारी प्राप्त की जा सकती है ?mtcarsजहां 'mtcars' सूची में डेटासेट में से एक है। अन्य पैकेजों में अतिरिक्त डेटासेट हो सकते हैं।

एक वेक्टर बनाना आसान है। कभी-कभी इसमें कुछ यादृच्छिकता जोड़ना आवश्यक होता है, और इसे बनाने के लिए कई प्रकार के कार्य होते हैं। sample()एक वेक्टर यादृच्छिक कर सकते हैं, या कुछ ही मूल्यों के साथ एक यादृच्छिक वेक्टर दे सकते हैं। lettersएक उपयोगी वेक्टर है जिसमें वर्णमाला है। इसका उपयोग कारक बनाने के लिए किया जा सकता है।

कुछ उदाहरण:

  • यादृच्छिक मूल्य: x <- rnorm(10)सामान्य वितरण के लिए, x <- runif(10)समान वितरण के लिए, ...
  • कुछ मूल्यों का क्रमचय: x <- sample(1:10)यादृच्छिक क्रम में वेक्टर 1:10 के लिए।
  • एक यादृच्छिक कारक: x <- sample(letters[1:4], 20, replace = TRUE)

मैट्रिसेस के लिए, कोई भी उपयोग कर सकता है matrix(), जैसे:

matrix(1:10, ncol = 2)

डेटा फ्रेम बनाना का उपयोग करके किया जा सकता है data.frame()। डेटा फ्रेम में प्रविष्टियों के नाम पर ध्यान देना चाहिए, और इसे अत्यधिक जटिल नहीं बनाना चाहिए।

एक उदाहरण :

set.seed(1)
Data <- data.frame(
    X = sample(1:10),
    Y = sample(c("yes", "no"), 10, replace = TRUE)
)

कुछ सवालों के लिए, विशिष्ट स्वरूपों की आवश्यकता हो सकती है। इन के लिए, एक प्रदान की के किसी भी उपयोग कर सकते हैं as.someType: कार्यों as.factor, as.Date, as.xtsवेक्टर और / या डेटा फ्रेम चाल के साथ संयोजन में, ... ये।

अपना डेटा कॉपी करें

आप कुछ डेटा है कि इन सुझावों का उपयोग निर्माण के लिए भी मुश्किल होगा है, तो आप हमेशा अपने मूल डेटा का एक उप कर सकते हैं, का उपयोग कर head(), subset()या सूचकांक। फिर dput()हमें कुछ ऐसा देने के लिए उपयोग करें जिसे तुरंत आर में रखा जा सके:

> dput(iris[1:4, ]) # first four rows of the iris data set
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")

यदि आपके डेटा फ़्रेम में कई स्तरों के साथ एक कारक है, तो dputआउटपुट अनजाने हो सकता है क्योंकि यह अभी भी सभी संभावित कारक स्तरों को सूचीबद्ध करेगा, भले ही वे आपके डेटा के सबसेट में मौजूद न हों। इस समस्या को हल करने के लिए, आप droplevels()फ़ंक्शन का उपयोग कर सकते हैं । नीचे दी गई सूचना कि कैसे प्रजातियां केवल एक स्तर का कारक है:

> dput(droplevels(iris[1: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")

उपयोग करते समय dput, आप केवल प्रासंगिक कॉलम को शामिल करना चाह सकते हैं:

> dput(mtcars[1:3, c(2, 5, 6)]) # first three rows of columns 2, 5, and 6
structure(list(cyl = c(6, 6, 4), drat = c(3.9, 3.9, 3.85), wt = c(2.62, 
2.875, 2.32)), row.names = c("Mazda RX4", "Mazda RX4 Wag", "Datsun 710"
), class = "data.frame")

इसके लिए एक अन्य चेतावनी dputयह है कि यह कुंजीकृत data.tableवस्तुओं के लिए या समूह tbl_df(वर्ग grouped_df) से काम नहीं करेगा dplyr। इन मामलों में आप, साझा करने से पहले एक नियमित रूप से डेटा फ्रेम करने के लिए वापस परिवर्तित कर सकते हैं dput(as.data.frame(my_data))

सबसे खराब स्थिति में, आप एक पाठ प्रतिनिधित्व दे सकते हैं जिसे textपैरामीटर के उपयोग से पढ़ा जा सकता है 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)

न्यूनतम कोड का उत्पादन

यह आसान हिस्सा होना चाहिए, लेकिन अक्सर ऐसा नहीं होता है। आपको जो नहीं करना चाहिए, वह है:

  • सभी प्रकार के डेटा रूपांतरण जोड़ें। सुनिश्चित करें कि प्रदान किया गया डेटा पहले से ही सही प्रारूप में है (जब तक कि समस्या की समस्या न हो)
  • एक पूरे फ़ंक्शन / कोड का एक कॉपी-पेस्ट करें जो एक त्रुटि देता है। सबसे पहले, यह पता लगाने की कोशिश करें कि कौन सी रेखाएं त्रुटि में परिणत होती हैं। अधिक बार आप यह नहीं जान पाएंगे कि समस्या स्वयं क्या है।

आपको क्या करना चाहिए, यह है:

  • जोड़ने अगर आप किसी भी (का उपयोग कर का उपयोग जो संकुल इस्तेमाल किया जाना चाहिए library())
  • यदि आप कनेक्शन खोलते हैं या फ़ाइलें बनाते हैं, तो उन्हें बंद करने या फ़ाइलों को हटाने के लिए कुछ कोड जोड़ें (उपयोग करके unlink())
  • यदि आप विकल्प बदलते हैं, तो सुनिश्चित करें कि कोड में मूल लोगों को वापस करने के लिए एक कथन शामिल है। (उदा op <- par(mfrow=c(1,2)) ...some code... par(op))
  • कोड को चलाने योग्य बनाने के लिए अपने कोड को एक नए, खाली R सत्र में चलाएं। लोग कंसोल में आपके डेटा और आपके कोड को सिर्फ कॉपी-पेस्ट करने में सक्षम होना चाहिए और आपके पास बिल्कुल वैसा ही होना चाहिए जैसा आपके पास है।

अतिरिक्त जानकारी दें

ज्यादातर मामलों में, बस आर संस्करण और ऑपरेटिंग सिस्टम पर्याप्त होगा। जब संघर्ष पैकेज के साथ उत्पन्न होता है, तो sessionInfo()वास्तव में मदद कर सकता है। अन्य अनुप्रयोगों के कनेक्शन के बारे में बात करते समय (यह ओडीबीसी या कुछ और के माध्यम से हो), एक को उन लोगों के लिए संस्करण संख्या भी प्रदान करनी चाहिए, और यदि संभव हो तो सेटअप पर आवश्यक जानकारी भी।

आप में अनुसंधान चल रहे हैं आर स्टूडियो का उपयोग कर rstudioapi::versionInfo()अपने RStudio संस्करण रिपोर्ट करने के लिए सहायक हो सकता है।

यदि आपको किसी विशिष्ट पैकेज से कोई समस्या है, तो आप आउटपुट देकर पैकेज का संस्करण प्रदान करना चाह सकते हैं packageVersion("name of the package")


1 नोट:set.seed() R> 3.6.0 और पिछले संस्करणों के बीच अंतर का आउटपुट । निर्दिष्ट करें कि आप किस R संस्करण का उपयोग यादृच्छिक प्रक्रिया के लिए करते हैं, और यदि आपको पुराने प्रश्नों का अनुसरण करते हुए थोड़ा अलग परिणाम मिलता है तो आश्चर्यचकित न हों। ऐसे मामलों में समान परिणाम प्राप्त करने के लिए, आप RNGversion()-function से पहले set.seed()(उदाहरण :) का उपयोग कर सकते हैं RNGversion("3.5.2")

595 hadley May 11 2011 at 20:57

(यहाँ मेरी सलाह है कि कैसे एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण लिखने के लिए । मैंने इसे छोटा लेकिन मीठा बनाने की कोशिश की है)

कैसे एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण लिखने के लिए।

यदि आप एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण प्रदान करते हैं, तो आपको अपनी आर समस्या के साथ अच्छी मदद मिलने की संभावना है। एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण किसी और को आर कोड को कॉपी और पेस्ट करके आपकी समस्या को फिर से बनाने की अनुमति देता है।

आपके उदाहरण के लिए प्रतिलिपि प्रस्तुत करने योग्य बनाने के लिए आपको चार चीजों की आवश्यकता है: आवश्यक पैकेज, डेटा, कोड, और आपके आर पर्यावरण का विवरण।

  • पैकेज को स्क्रिप्ट के शीर्ष पर लोड किया जाना चाहिए, इसलिए यह देखना आसान है कि किन लोगों को उदाहरण की आवश्यकता है।

  • ईमेल या स्टैक ओवरफ्लो प्रश्न में डेटा शामिल करने का सबसे आसान तरीका है dput()कि आर कोड को फिर से बनाने के लिए इसका उपयोग किया जाए। उदाहरण के लिए, mtcarsडेटासेट को R में फिर से बनाने के लिए , मैं निम्नलिखित चरणों का पालन करूँगा:

    1. dput(mtcars)आर में चला
    2. आउटपुट की प्रतिलिपि बनाएँ
    3. मेरी प्रतिलिपि प्रस्तुत करने योग्य लिपि में, mtcars <-फिर टाइप करें।
  • यह सुनिश्चित करने में थोड़ा समय व्यतीत करें कि आपका कोड दूसरों के लिए पढ़ना आसान है:

    • सुनिश्चित करें कि आपने रिक्त स्थान का उपयोग किया है और आपके चर नाम संक्षिप्त हैं, लेकिन जानकारीपूर्ण हैं

    • आपकी समस्या कहां है, यह बताने के लिए टिप्पणियों का उपयोग करें

    • समस्या से संबंधित नहीं है जो सब कुछ को दूर करने के लिए अपनी पूरी कोशिश करें।
      आपका कोड जितना छोटा होगा, समझने में उतना आसान होगा।

  • sessionInfo()अपने कोड में एक टिप्पणी के आउटपुट को शामिल करें । यह आपके R वातावरण को सारांशित करता है और अगर आप आउट-ऑफ-डेट पैकेज का उपयोग कर रहे हैं, तो यह जांचना आसान बनाता है।

आप देख सकते हैं कि आपने वास्तव में एक नया आर सत्र शुरू करके और अपनी स्क्रिप्ट को चिपकाकर एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण बनाया है।

ईमेल में अपना सभी कोड डालने से पहले, इसे जिस्ट गीथब पर रखने पर विचार करें । यह आपके कोड को अच्छा सिंटैक्स हाइलाइटिंग देगा, और आपको ईमेल सिस्टम द्वारा मंगाई गई किसी भी चीज़ के बारे में चिंता करने की ज़रूरत नहीं है।

307 RomanLuštrik May 11 2011 at 18:22

व्यक्तिगत रूप से, मैं "एक" लाइनर्स पसंद करता हूं। रेखाओं के साथ कुछ:

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)

डेटा संरचना को लेखक की समस्या के विचार की नकल करनी चाहिए, न कि सटीक शब्द संरचना की। मैं वास्तव में इसकी सराहना करता हूं, जब चर मेरे स्वयं के चर या भगवान को मना नहीं करते हैं, कार्य (जैसे df)।

वैकल्पिक रूप से, कोई कुछ कोनों को काट सकता है और पहले से मौजूद डेटा सेट को इंगित कर सकता है, जैसे कुछ:

library(vegan)
data(varespec)
ord <- metaMDS(varespec)

अपने द्वारा उपयोग किए जा रहे किसी विशेष पैकेज का उल्लेख करना न भूलें।

यदि आप बड़ी वस्तुओं पर कुछ प्रदर्शित करने की कोशिश कर रहे हैं, तो आप कोशिश कर सकते हैं

my.df2 <- data.frame(a = sample(10e6), b = sample(letters, 10e6, replace = TRUE))

यदि आप rasterपैकेज के माध्यम से स्थानिक डेटा के साथ काम कर रहे हैं , तो आप कुछ यादृच्छिक डेटा उत्पन्न कर सकते हैं। पैकेज विगनेट में बहुत सारे उदाहरण मिल सकते हैं, लेकिन यहां एक छोटी सी डली है।

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)

यदि आपको किसी स्थानिक वस्तु की आवश्यकता है जैसा कि कार्यान्वित किया गया है sp, तो आप "स्थानिक" पैकेजों में बाहरी फ़ाइलों (जैसे ESRI शेपफाइल) के माध्यम से कुछ डेटासेट प्राप्त कर सकते हैं (कार्य दृश्य में स्थानिक दृश्य देखें)।

library(rgdal)
ogrDrivers()
dsn <- system.file("vectors", package = "rgdal")[1]
ogrListLayers(dsn)
ogrInfo(dsn=dsn, layer="cities")
cities <- readOGR(dsn=dsn, layer="cities")
281 RicardoSaporta May 14 2013 at 05:20

इस पोस्ट से प्रेरित होकर, अब
reproduce(<mydata>)जब मैं StackOverflow को पोस्ट करने की आवश्यकता है, तो मैं एक आसान फ़ंक्शन का उपयोग करता हूं।


त्वरित निर्देश

यदि myDataआपके ऑब्जेक्ट का नाम पुन: उत्पन्न करने के लिए है, तो R में निम्न को चलाएँ:

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

reproduce(myData)

Details:

This function is an intelligent wrapper to dput and does the following:

  • automatically samples a large data set (based on size and class. Sample size can be adjusted)
  • creates a dput output
  • allows you to specify which columns to export
  • appends to the front of it objName <- ... so that it can be easily copy+pasted, but...
  • If working on a mac, the output is automagically copied to the clipboard, so that you can simply run it and then paste to your question.

The source is available here:

  • Github - pubR/reproduce.R

Example:

# 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 is about 100 x 102. I want to sample 10 rows, and a few specific columns

reproduce(DF, cols=c("id", "X1", "X73", "Class"))  # I could also specify the column number. 

Gives the following output:

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

Notice also that the entirety of the output is in a nice single, long line, not a tall paragraph of chopped up lines. This makes it easier to read on SO questions posts and also easier to copy+paste.


Update Oct 2013:

You can now specify how many lines of text output will take up (ie, what you will paste into StackOverflow). Use the lines.out=n argument for this. Example:

reproduce(DF, cols=c(1:3, 17, 23), lines.out=7) yields:

    ==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==
198 SachaEpskamp May 11 2011 at 18:21

Here is a good guide.

The most important point is: Just make sure that you make a small piece of code that we can run to see what the problem is. A useful function for this is dput(), but if you have very large data, you might want to make a small sample dataset or only use the first 10 lines or so.

EDIT:

Also make sure that you identified where the problem is yourself. The example should not be an entire R script with "On line 200 there is an error". If you use the debugging tools in R (I love browser()) and Google you should be able to really identify where the problem is and reproduce a trivial example in which the same thing goes wrong.

167 RichieCotton May 11 2011 at 20:17

The R-help mailing list has a posting guide which covers both asking and answering questions, including an example of generating data:

Examples: Sometimes it helps to provide a small example that someone can actually run. For example:

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")

)

The word small is especially important. You should be aiming for a minimal reproducible example, which means that the data and the code should be as simple as possible to explain the problem.

EDIT: Pretty code is easier to read than ugly code. Use a style guide.

164 Paolo Jun 29 2012 at 15:32

Since R.2.14 (I guess) you can feed your data text representation directly to 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
") 
146 BenBolker Jul 15 2011 at 02:49

Sometimes the problem really isn't reproducible with a smaller piece of data, no matter how hard you try, and doesn't happen with synthetic data (although it's useful to show how you produced synthetic data sets that did not reproduce the problem, because it rules out some hypotheses).

  • Posting the data to the web somewhere and providing a URL may be necessary.
  • If the data can't be released to the public at large but could be shared at all, then you may be able to offer to e-mail it to interested parties (although this will cut down the number of people who will bother to work on it).
  • I haven't actually seen this done, because people who can't release their data are sensitive about releasing it any form, but it would seem plausible that in some cases one could still post data if it were sufficiently anonymized/scrambled/corrupted slightly in some way.

If you can't do either of these then you probably need to hire a consultant to solve your problem ...

edit: Two useful SO questions for anonymization/scrambling:

  • How to create example data set from private data (replacing variable names and levels with uninformative place holders)?
  • Given a set of random numbers drawn from a continuous univariate distribution, find the distribution
136 AriB.Friedman Jul 09 2012 at 22:41

The answers so far are obviously great for the reproducibility part. This is merely to clarify that a reproducible example cannot and should not be the sole component of a question. Don't forget to explain what you want it to look like and the contours of your problem, not just how you have attempted to get there so far. Code is not enough; you need words also.

Here's a reproducible example of what to avoid doing (drawn from a real example, names changed to protect the innocent):


The following is sample data and part of function I have trouble with.

code
code
code
code
code (40 or so lines of it)

How can I achieve this ?


124 jasmine_007 Feb 20 2014 at 16:11

I have a very easy and efficient way to make a R example that has not been mentioned above. You can define your structure firstly. For example,

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

>fix(mydata)

Then you can input your data manually. This is efficient for smaller examples rather than big ones.

119 JT85 Apr 10 2013 at 21:51

To quickly create a dput of your data you can just copy (a piece of) the data to your clipboard and run the following in R:

for data in Excel:

dput(read.table("clipboard",sep="\t",header=TRUE))

for data in a txt file:

dput(read.table("clipboard",sep="",header=TRUE))

You can change the sep in the latter if necessary. This will only work if your data is in the clipboard of course.

118 BrodieG Feb 12 2015 at 22:24

Guidelines:


Your main objective in crafting your questions should be to make it as easy as possible for readers to understand and reproduce your problem on their systems. To do so:

  1. Provide input data
  2. Provide expected output
  3. Explain your problem succinctly
    • if you have over 20 lines of text + code you can probably go back and simplify
    • simplify your code as much as possible while preserving the problem/error

This does take some work but seems like a fair trade-off since you are asking others to do work for you.

Providing Data:


Built-in Data Sets

The best option by far is to rely on built-in datasets. This makes it very easy for others to work on your problem. Type data() at the R prompt to see what data is available to you. Some classic examples:

  • iris
  • mtcars
  • ggplot2::diamonds (external package, but almost everyone has it)

Inspect the built-in datasets, to find one suitable for your problem.

If you are able to rephrase your problem to use the built-in datasets you are much more likely to get good answers (and upvotes).

Self Generated Data

If your problem is very specific to a type of data that is not represented in the existing data sets, then provide the R code that generates the smallest possible dataset that your problem manifests itself on. For example

set.seed(1)  # important to make random data reproducible
myData <- data.frame(a=sample(letters[1:5], 20, rep=T), b=runif(20))

Now someone trying to answer my question can copy/paste those two lines and start working on the problem immediately.

dput

As a last resort, you can use dput to transform a data object to R code (e.g. dput(myData)). I say as a "last resort" because the output of dput is often fairly unwieldy, annoying to copy-paste, and obscures the rest of your question.

Provide Expected Output:


Someone once said:

A picture of expected output is worth 1000 words

-- a very wise person

If you can add something like "I expected to get this result":

   cyl   mean.hp
1:   6 122.28571
2:   4  82.63636
3:   8 209.21429

to your question, people are much more likely to quickly understand what you are trying to do. If your expected result is large and unwieldy, then you probably haven't thought enough about how to simplify your problem (see next).

Explain Your Problem Succinctly


The main thing to do is to simplify your problem as much as possible before you ask your question. Re-framing the problem to work with the built-in datasets will help a lot in this regard. You will also often find that just by going through the process of simplification you will answer your own problem.

Here are some examples of good questions:

  • with built in data set
  • with user generated data

In both cases, the user's problems are almost certainly not with the simple examples they provide. Rather they abstracted the nature of their problem and applied it to a simple data set to ask their question.

Why Yet Another Answer To This Question?


This answer focuses on what I think is the best practice: use built-in data sets and provide what you expect as a result in a minimal form. The most prominent answers focus on other aspects. I don't expect this answer to rising to any prominence; this is here solely so that I can link to it in comments to newbie questions.

113 daniel Nov 27 2014 at 09:02

Reproducible code is key to get help. However, there are many users that might be skeptical of pasting even a chunk of their data. For instance, they could be working with sensitive data or on an original data collected to use in a research paper. For any reason, I thought it would be nice to have a handy function for "deforming" my data before pasting it publicly. The anonymize function from the package SciencesPo is very silly, but for me it works nicely with dput function.

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

Then I anonymize it:

> 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

One may also want to sample few variables instead of the whole data before apply anonymization and dput command.

    # 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
102 userJT Feb 22 2013 at 22:29

Often you need some data for an example, however, you don't want to post your exact data. To use some existing data.frame in established library, use data command to import it.

e.g.,

data(mtcars)

and then do the problem

names(mtcars)
your problem demostrated on the mtcars data set
92 TMS Jan 04 2014 at 02:07

If you have large dataset which cannot be easily put to the script using dput(), post your data to pastebin and load them using read.table:

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

Inspired by @Henrik.

90 TylerRinker Jun 11 2015 at 20:57

I am developing the wakefield package to address this need to quickly share reproducible data, sometimes dput works fine for smaller data sets but many of the problems we deal with are much larger, sharing such a large data set via dput is impractical.

About:

wakefield allows the user to share minimal code to reproduce data. The user sets n (number of rows) and specifies any number of preset variable functions (there are currently 70) that mimic real if data (things like gender, age, income etc.)

Installation:

Currently (2015-06-11), wakefield is a GitHub package but will go to CRAN eventually after unit tests are written. To install quickly, use:

if (!require("pacman")) install.packages("pacman")
pacman::p_load_gh("trinker/wakefield")

Example:

Here is an example:

r_data_frame(
    n = 500,
    id,
    race,
    age,
    sex,
    hour,
    iq,
    height,
    died
)

This produces:

    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
.. ...   ... ...    ...      ... ...    ...   ...
73 docendodiscimus Jan 09 2015 at 22:09

If you have one or more factor variable(s) in your data that you want to make reproducible with dput(head(mydata)), consider adding droplevels to it, so that levels of factors that are not present in the minimized data set are not included in your dput output, in order to make the example minimal:

dput(droplevels(head(mydata)))
66 CMichael Jan 09 2015 at 20:11

I wonder if an http://old.r-fiddle.org/ link could be a very neat way of sharing a problem. It receives a unique ID like and one could even think about embedding it in SO.

49 user2100721 Jul 22 2016 at 17:01

Please do not paste your console outputs like this:

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")
)

We can not copy-paste it directly.

To make questions and answers properly reproducible, try to remove + & > before posting it and put # for outputs and comments like this:

#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")

One more thing, if you have used any function from certain package, mention that library.

34 andrii Aug 19 2017 at 02:02

You can do this using reprex.

As mt1022 noted, "... good package for producing minimal, reproducible example is "reprex" from tidyverse".

According to Tidyverse:

The goal of "reprex" is to package your problematic code in such a way that other people can run it and feel your pain.

An example is given on tidyverse web site.

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

I think this is the simplest way to create a reproducible example.

33 5revs,2users84%user5947301 Apr 20 2016 at 17:50

Apart of all above answers which I found very interesting, it could sometimes be very easy as it is discussed here :- HOW TO MAKE A MINIMAL REPRODUCIBLE EXAMPLE TO GET HELP WITH R

There are many ways to make a random vector Create a 100 number vector with random values in R rounded to 2 decimals or random matrix in R

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

Note that sometimes it is very difficult to share a given data because of various reasons such as dimension etc. However, all above answers are great and very important to think and use when one wants to make a reproducible data example. But note that in order to make a data as representative as the original (in case the OP cannot share the original data), it is good to add some information with the data example as (if we call the data mydf1)

class(mydf1)
# this shows the type of the data you have 
dim(mydf1)
# this shows the dimension of your data

Moreover, one should know the type, length and attributes of a data which can be Data structures

#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))
28 TheRimalaya Apr 10 2016 at 01:15

Here are some of my suggestions:

  • Try to use default R datasets
  • If you have your own dataset, include them with dput, so others can help you more easily
  • Do not use install.package() unless it is really necessary, people will understand if you just use require or library
  • Try to be concise,

    • Have some dataset
    • Try to describe the output you need as simply as possible
    • Do it yourself before you ask the question
  • It is easy to upload an image, so upload plots if you have
  • Also include any errors you may have

All these are part of a reproducible example.

18 dank Apr 05 2017 at 04:08

It's a good idea to use functions from the testthat package to show what you expect to occur. Thus, other people can alter your code until it runs without error. This eases the burden of those who would like to help you, because it means they don't have to decode your textual description. For example

library(testthat)
# code defining x and y
if (y >= 10) {
    expect_equal(x, 1.23)
} else {
    expect_equal(x, 3.21)
}

is clearer than "I think x would come out to be 1.23 for y equal to or exceeding 10, and 3.21 otherwise, but I got neither result". Even in this silly example, I think the code is clearer than the words. Using testthat lets your helper focus on the code, which saves time, and it provides a way for them to know they have solved your problem, before they post it