優れたRの再現可能な例を作成する方法

May 11 2011

同僚とパフォーマンスについて話し合ったり、教えたり、バグレポートを送信したり、メーリングリストやここStack Overflowでガイダンスを検索したりするときは、再現可能な例がよく聞かれ、常に役立ちます。

優れた例を作成するためのヒントは何ですか?rのデータ構造をテキスト形式でどのように貼り付けますか?他にどのような情報を含める必要がありますか?

加えて、そこに他のトリックを使用するようにしているdput()dump()またはstructure()library()またはrequire()ステートメントをいつ含める必要がありますか?言葉1つの避けなければならない、に加えて予約されたcdfdata、などを?

どのようにして偉大作るんR再現性の例を?

回答

1756 JorisMeys May 11 2011 at 18:40

最小の再現の例では、以下の項目で構成されています。

  • 問題を実証するために必要な最小限のデータセット
  • エラーを再現するために必要な最小限の実行可能なコード。これは、特定のデータセットで実行できます。
  • 使用されているパッケージ、Rバージョン、およびそれが実行されているシステムに関する必要な情報。
  • ランダムプロセスの場合、set.seed()再現性のためのシード(によって設定)1

再現性のある最小限の優れたについては、使用している関数のヘルプファイルを参照してください。一般に、そこに示されているすべてのコードは、最小限の再現可能な例の要件を満たしています。データが提供され、最小限のコードが提供され、すべてが実行可能です。また、賛成票が多いStackOverflowの質問もご覧ください。

最小限のデータセットの作成

ほとんどの場合、これは、ベクトル/データフレームにいくつかの値を指定するだけで簡単に実行できます。または、ほとんどのパッケージで提供されている組み込みデータセットの1つを使用できます。
組み込みデータセットの包括的なリストは、で見ることができますlibrary(help = "datasets")。すべてのデータセットには簡単な説明があり、たとえば?mtcars「mtcars」がリスト内のデータセットの1つである場合など、より多くの情報を取得できます。他のパッケージには、追加のデータセットが含まれている場合があります。

ベクトルの作成は簡単です。ランダム性を追加する必要がある場合もありますが、それを実現するための関数は多数あります。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)
)

一部の質問では、特定の形式が必要になる場合があります。これらの場合、1は、提供のいずれかを使用することができますas.someType:関数as.factoras.Dateas.xtsベクターおよび/またはデータフレームのトリックとの組み合わせで、...これらを。

データをコピーする

これらのヒントを使用して構築するのが難しすぎるデータがある場合は、、またはインデックスを使用してhead()、いつでも元のデータのサブセットを作成できsubset()ます。次に、を使用dput()して、すぐにRに入れることができるものを提供します。

> 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()関数を使用できます。以下に、種が1つのレベルのみの要因であることに注意してください。

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

もう1つの注意点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セッションでコードをテスト実行して、コードが実行可能であることを確認します。人々はあなたのデータとあなたのコードをコンソールにコピーアンドペーストするだけで、あなたが持っているものとまったく同じものを手に入れることができるはずです。

追加情報を提供する

ほとんどの場合、Rバージョンとオペレーティングシステムだけで十分です。パッケージとの競合が発生した場合、の出力を提供sessionInfo()することは非常に役立ちます。他のアプリケーションへの接続(ODBCなどを介したもの)について話すときは、それらのバージョン番号も提供する必要があります。可能であれば、セットアップに関する必要な情報も提供する必要があります。

R StudioRを実行している場合は、を使用しrstudioapi::versionInfo()てRStudioのバージョンを報告すると便利です。

特定のパッケージに問題がある場合は、の出力を指定してパッケージのバージョンを提供することをお勧めしますpackageVersion("name of the package")


1 注:の出力set.seed()は、R> 3.6.0と以前のバージョンで異なります。ランダムプロセスに使用したRバージョンを指定してください。古い質問に従うと、わずかに異なる結果が得られても驚かないでください。このような場合に同じ結果を得るには、RNGversion()前にset.seed()-関数を使用できます(例:) RNGversion("3.5.2")

595 hadley May 11 2011 at 20:57

(再現可能な例の書き方からのアドバイスです。短くても甘いものにしようとしました)

再現可能な例の書き方。

再現可能な例を提供すれば、Rの問題について良い助けを得る可能性が最も高くなります。再現可能な例では、Rコードをコピーして貼り付けるだけで、他の誰かが問題を再現できます。

例を再現可能にするために含める必要があるものは、必要なパッケージ、データ、コード、およびR環境の説明の4つです。

  • パッケージはスクリプトの先頭にロードする必要があるため、例で必要なパッケージを簡単に確認できます。

  • 電子メールまたはStackOverflowの質問にデータを含める最も簡単な方法は、を使用dput()してRコードを生成し、データを再作成することです。たとえばmtcars、Rでデータセットを再作成するには、次の手順を実行します。

    1. dput(mtcars)Rで実行
    2. 出力をコピーします
    3. 再現可能なスクリプトで、入力してmtcars <-から貼り付けます。
  • あなたのコードが他の人に読みやすいことを確認するために少し時間を費やしてください:

    • スペースを使用し、変数名が簡潔でありながら有益であることを確認してください

    • コメントを使用して、問題がどこにあるかを示します

    • 問題に関係のないものはすべて削除するように最善を尽くします。
      コードが短いほど、理解しやすくなります。

  • の出力をsessionInfo()コードのコメントに含めます。これにより、R環境が要約され、古いパッケージを使用しているかどうかを簡単に確認できます。

新しいRセッションを開始し、スクリプトをに貼り付けることで、実際に再現可能な例を作成したことを確認できます。

すべてのコードをメールに入れる前に、Gistgithubに入れることを検討してください。それはあなたのコードに素晴らしい構文のハイライトを与えるでしょう、そしてあなたは何も電子メールシステムによって壊されることを心配する必要はありません。

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)

詳細:

この関数はインテリジェントなラッパーdputであり、以下を実行します。

  • 大きなデータセットを自動的にサンプリングします(サイズとクラスに基づきます。サンプルサイズは調整可能です)
  • dput出力を作成します
  • エクスポートする列を指定できます
  • objName <- ...簡単にコピーして貼り付けることができるように前面に追加しますが...
  • Macで作業している場合、出力は自動的にクリップボードにコピーされるため、実行してから質問に貼り付けることができます。

ソースはここにあります:

  • Github-pubR / reproduce.R

例:

# 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は約100x 102です。10行といくつかの特定の列をサンプリングしたい

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

また、出力全体が、切り刻まれた行の長い段落ではなく、1つの長い行になっていることにも注意してください。これにより、SOの質問の投稿が読みやすくなり、コピーと貼り付けも簡単になります。


2013年10月の更新:

これで、テキスト出力の何行を占めるか(つまり、StackOverflowに何を貼り付けるか)を指定できます。lines.out=nこれには引数を使用します。例:

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

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

ここに良いガイドがあります。

最も重要な点は次のとおりです問題が何であるかを確認するために実行できる小さなコードを作成するようにしてください。これに役立つ関数はですがdput()、データが非常に大きい場合は、小さなサンプルデータセットを作成するか、最初の10行程度のみを使用することをお勧めします。

編集:

また、問題が自分自身のどこにあるかを特定したことを確認してください。この例は、「200行目にエラーがあります」というRスクリプト全体であってはなりません。R(大好きbrowser())とGoogleのデバッグツールを使用すると、問題がどこにあるのかを実際に特定し、同じことがうまくいかないという些細な例を再現できるはずです。

167 RichieCotton May 11 2011 at 20:17

R-helpメーリングリストには、データ生成の例を含め、質問の質問と回答の両方をカバーする投稿ガイドがあります。

例:誰かが実際に実行できる小さな例を提供すると役立つ場合があります。例えば:

次のような行列xがある場合:

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

次のように、8行、「row」、「col」、「value」という名前の3つの列があり、ディメンション名が「row」と「col」の値であるデータフレームに変換するにはどうすればよいですか。

  > x.df
     row col value
  1    A   x      1

...
(答えは次のようになります:

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

小さいという言葉は特に重要です。再現性のある最小限の例を目指す必要があります。つまり、問題を説明するためにデータとコードをできるだけ単純にする必要があります。

編集:きれいなコードは醜いコードよりも読みやすいです。スタイルガイドを使用します。

164 Paolo Jun 29 2012 at 15:32

R.2.14以降(私は推測します)、データテキスト表現を直接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

時々 、問題は、実際にデータの小さな作品は、あなたがしよういかに難しいかを問わずと再現性がない、そしてそれはあなたがた合成データセット生成方法を示すために便利ですが、(合成データでは発生しませんではない問題を再現しているため、それはいくつかの仮説を除外します)。

  • データをWebのどこかに投稿し、URLを提供する必要がある場合があります。
  • データを一般に公開することはできなくても共有できる場合は、関係者に電子メールで送信することを提案できる場合があります(ただし、これにより、わざわざ仕事をする人の数が減ります)。その上)。
  • データをリリースできない人はどのような形式でもデータをリリースすることに敏感なので、実際にこれが行われるのを見たことがありませんが、データが十分に匿名化/スクランブル/破損していれば、データを投稿できる場合もあると思われます何らかの方法で。

これらのいずれかを実行できない場合は、おそらく問題を解決するためにコンサルタントを雇う必要があります...

編集:匿名化/スクランブリングのための2つの有用なSO質問:

  • プライベートデータからサンプルデータセットを作成する方法(変数名とレベルを情報のないプレースホルダーに置き換える)?
  • 連続単変量分布から引き出された一連の乱数が与えられた場合、分布を見つけます
136 AriB.Friedman Jul 09 2012 at 22:41

これまでの答えは、再現性の部分にとって明らかに素晴らしいものです。これは、再現可能な例が質問の唯一の構成要素になることはできず、またそうすべきではないことを明確にするためだけのものです。これまでにどのように到達しようとしたかだけでなく、どのように見せたいか、問題の輪郭を説明することを忘れないでください。コードだけでは不十分です。言葉も必要です。

これは、避けるべきことの再現可能な例です(実際の例から引用し、無実を保護するために名前を変更しました)。


以下はサンプルデータと私が問題を抱えている機能の一部です。

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

どうすればこれを達成できますか?


124 jasmine_007 Feb 20 2014 at 16:11

上記に記載されていないRの例を作成する非常に簡単で効率的な方法があります。最初に構造を定義できます。例えば、

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