如何制作一个很好的R可重复的例子

Andrie 2474 r r-faq

在与同事讨论性能,教学,发送错误报告或在邮件列表上搜索指导时,以及在Stack Overflow上,通常会询问可重复的示例并始终提供帮助.

您有什么建议创建优秀示例的提示?如何以文本格式粘贴中的数据结构?您还应该包含哪些其他信息?

在另外还有其他招数来使用dput(),dump()structure()?你什么时候应该包括library()require()声明?其中保留字应避免一个,此外c,df,data等?

怎样才能成为一位伟大的重复的例子?

Joris Meys.. 1661

最小可重复的示例包括以下项目:

  • 重现错误所必需的最小数据集
  • 重现错误所需的最小可运行代码,可以在给定数据集上运行.
  • 有关所使用的软件包,R版本及其运行系统的必要信息.
  • 在随机过程的情况下,种子(由...设定set.seed())用于再现性

查看已使用函数的帮助文件中的示例通常很有帮助.通常,那里给出的所有代码都满足最小可重现示例的要求:提供数据,提供最少的代码,并且一切都是可运行的.

生成最小数据集

对于大多数情况,只需提供带有某些值的矢量/数据帧即可轻松完成.或者您可以使用大多数软件包提供的内置数据集之一.
可以看到内置数据集的完整列表set.seed().每个数据集都有一个简短的描述,可以获得更多信息,例如library(help = "datasets")"mtcars"是列表中的一个数据集.其他包可能包含其他数据集.

制作矢量很容易.有时需要为它添加一些随机性,并且有许多功能可以实现.?mtcars可以随机化一个向量,或者给出一个只有几个值的随机向量.sample()是一个包含字母表的有用矢量.这可以用于制作因素.

几个例子:

  • 随机值:letters正态分布,x <- rnorm(10)均匀分布,......
  • 一些值的排列:x <- runif(10)对于矢量1:10的随机顺序.
  • 随机因素: x <- sample(1:10)

对于矩阵,可以使用x <- sample(letters[1:4], 20, replace = TRUE),例如:

matrix(1:10, ncol = 2)

制作数据帧可以使用matrix().应注意在数据框中命名条目,并且不要使其过于复杂.

一个例子 :

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

对于某些问题,可能需要特定格式.对于这些,可以使用任何的提供data.frame():功能as.someType,as.factor,as.Date结合的载体和/或数据帧的技巧,...这些.

复制您的数据

如果你有一些数据,这将是太难使用这些技巧来构建,那么你可以随时让你的原始数据的子集,例如使用as.xts,head()或索引.然后用eg.subset()给我们一些可以立即放入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()输出可能不实用,因为它仍将列出所有可能的因子级别,即使它们不存在于数据子集中.要解决此问题,您可以使用该dput功能.请注意下面的物种是如何只有一个水平的因素:

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

另一个警告droplevels()是,它不适用于键控dput对象或分组dput(类data.table)tbl_df.在这些情况下,您可以在共享之前转换回常规数据框grouped_df.

最糟糕的情况是,您可以使用以下dplyr参数提供可以读取的文本表示dput(as.data.frame(my_data)):

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

生成最少的代码

这应该是容易的部分,但往往不是.你不应该做的是:

  • 添加所有类型的数据转换.确保提供的数据格式正确(除非这是问题)
  • 复制粘贴一个产生错误的整个函数/代码块.首先,尝试找出确切导致错误的行.通常情况下,你会发现自己的问题.

你应该做的是:

  • 如果你使用任何(使用text)添加应该使用的包
  • 如果您打开连接或创建文件,添加一些代码来关闭它们或删除文件(使用read.table)
  • 如果更改选项,请确保代码包含一个语句,以将其还原为原始语句.(例如library())
  • 测试在新的空R会话中运行您的代码,以确保代码可运行.人们应该能够在控制台中复制粘贴您的数据和代码,并获得与您完全相同的信息.

提供额外信息

在大多数情况下,仅R版本和操作系统就足够了.当与包发生冲突时,给出输出unlink()确实可以提供帮助.在谈论与其他应用程序的连接时(无论是通过ODBC还是其他任何应用程序),还应该为这些应用程序提供版本号,如果可能,还应提供有关设置的必要信息.

如果您在运行v [R Studio的使用op <- par(mfrow=c(1,2)) ...some code... par(op)可以帮助您的报告版本RStudio.

如果您遇到特定包的问题,​​可能需要通过提供输出来提供包的版本sessionInfo().

  • @BgnR您可以使用索引提取部分数据框,例如:`tmp < - mydf [50:70,]`后跟`dput(mydf)`.如果数据框非常大,请尝试隔离问题并提交导致问题的几行. (26认同)
  • 如果数据帧非常大并且问题是由数据帧的中间产生的,那么如何使用`dput`?有没有办法使用`dput`来重现数据的中间部分,比如60到70行? (5认同)
  • @JorisMeys:仅供参考 - 在上面的评论中发布的问题是一个单独的问题:http://stackoverflow.com/questions/25127026/limiting-size-of-hierarchical-data-for-reproducible-example. (4认同)
  • @JorisMeys:有没有办法告诉`head`或`dput`将数据递归限制到N级?我正在尝试提供可重现的示例,我的数据是一个数据框列表.所以,`dput(head(myDataObj))`似乎还不够,因为它生成了14MB大小的输出文件. (3认同)
  • @Konrad你能做的最好的事情是链接到文件并给出最小的命令来读取该文件.这比复制粘贴dput()的输出要麻烦得少:) (3认同)
  • 只是想添加一个简单的方法来压缩`dput`输出,这样它就不会挤满你的帖子或分散注意力:获取[sublime text](https://www.sublimetext.com/)(它是免费的),将`dput`输出粘贴到sublime中.按"Ctrl + A","Ctrl + Shift + L","右箭头"键,"Del".现在一切都在一条线上.将其粘贴到Stack Overflow中,前面有4个空格,它只会占据你帖子的一行. (3认同)
  • @Travis Heeter:你应该为此使用R!例如`cat(capture.output(dput(mtcars)))` (2认同)

hadley.. 577

(这是我对如何写一个可重复的例子的建议.我试图让它变短但很甜)

如何编写可重现的示例.

如果您提供可重现的示例,您最有可能获得R问题的良好帮助.一个可重现的示例允许其他人通过复制和粘贴R代码来重新创建您的问题.

为了使您的示例可重现,您需要包含四件事:所需的包,数据,代码和R环境的描述.

  • 应该在脚本的顶部加载,因此很容易看到示例需要哪些包.

  • 在电子邮件或Stack Overflow问题中包含数据的最简单方法是使用dput()生成R代码来重新创建它.例如,要mtcars在R中重新创建数据集,我将执行以下步骤:

    1. dput(mtcars)在R中运行
    2. 复制输出
    3. 在我可重现的脚本中,键入mtcars <-然后粘贴.
  • 花一点时间确保您的代码易于其他人阅读:

    • 确保你已经使用了空格,你的变量名称简洁,但信息丰富

    • 使用注释来指出问题所在

    • 尽力删除与问题无关的所有内容.
      代码越短,理解起来就越容易.

  • sessionInfo()在代码中包含注释的输出.这总结了您的R环境,并且可以轻松检查您是否使用了过时的软件包.

你可以通过启动一个新的R会话并粘贴你的脚本来检查你是否真的做了一个可重现的例子.

在将所有代码放入电子邮件之前,请考虑将其放在Gist github上.它将为您的代码提供良好的语法突出显示,并且您不必担心电子邮件系统会破坏任何内容.

  • `tidyverse`中的`reprex`是一个很好的包,用于生成最小的,可重现的示例:https://github.com/tidyverse/reprex (21认同)
  • 我经常接收带有代码的电子邮件.我甚至收到附有包含代码的附加word文档的电子邮件.有时我甚至会收到包含SCREENSHOTS代码的附加word文档的电子邮件. (16认同)

Roman Luštri.. 299

就个人而言,我更喜欢"一个"衬里.一些事情:

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 shapefile)获取一些数据集(请参阅任务视图中的空间视图).

library(rgdal)
ogrDrivers()
dsn <- system.file("vectors", package = "rgdal")[1]
ogrListLayers(dsn)
ogrInfo(dsn=dsn, layer="cities")
cities <- readOGR(dsn=dsn, layer="cities")


Ricardo Sapo.. 271

受到这篇帖子的启发,我现在
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上工作,输出会自动复制到剪贴板,这样您只需运行它然后粘贴到您的问题.

来源可在此处获得:


例:

# 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约为100 x 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==

另请注意,输出的整体是一个很好的单行,长行,而不是一段很高的切断线.这样可以更容易阅读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==


Sacha Epskam.. 191

这是一个很好的指南:

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

但最重要的是:只要确保你制作了一小段我们可以运行的代码来查看问题所在.对此有用的功能是dput(),但如果您有非常大的数据,您可能想要制作一个小样本数据集或仅使用前10行左右.

编辑:

还要确保您确定问题出在哪里.该示例不应该是整个R脚本,"On line 200存在错误".如果您使用R(我喜欢browser())和谷歌中的调试工具,您应该能够真正确定问题所在,并重现一个简单的例子,其中同样的事情出错了.


Richie Cotto.. 163

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"的三列,其维度名称为"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")

)

小字这个词特别重要.您应该瞄准一个可重复性最小的示例,这意味着数据和代码应尽可能简单地解释问题.

编辑:漂亮的代码比丑陋的代码更容易阅读.使用样式指南.


Paolo.. 160

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

  • 你也可以使用`read.table("clipboard",header = TRUE)`. (26认同)
  • @ sebastian-c如何制作可重复的例子?:) (3认同)

Ben Bolker.. 143

有时,无论您尝试多么努力,问题都无法通过较小的数据再现,并且合成数据不会发生(尽管显示您如何生成不能重现问题的合成数据集很有用,因为它排除了一些假设).

  • 可能需要将数据发布到某处并提供URL.
  • 如果数据无法向公众发布但可以共享,那么您可以通过电子邮件将其发送给感兴趣的各方(尽管这会减少需要工作的人数)在上面).
  • 我实际上没有看到这样做,因为无法发布数据的人对于以任何形式发布数据都很敏感,但似乎有理由认为,如果有足够的匿名/加密/损坏数据,人们仍然可以发布数据某种程度上来说.

如果您不能做其中任何一项,那么您可能需要聘请一名顾问来解决您的问题......

编辑:匿名/加扰的两个有用的SO问题:


Ari B. Fried.. 133

到目前为止,答案对于再现性部分来说显然是很好的.这仅仅是为了澄清一个可重复的例子不能也不应该是问题的唯一组成部分.不要忘记解释你想要它的样子和问题的轮廓,而不仅仅是你到目前为止试图到达那里的方式.代码还不够; 你也需要单词.

这是一个可重复的例子,说明要避免做什么(从一个真实的例子中提取,名称改为保护无辜者):


以下是我遇到问题的示例数据和部分功能.

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

我怎样才能做到这一点?



小智.. 120

我有一个非常简单有效的方法来制作一个上面没有提到的R例子.您可以先定义结构.例如,

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

>fix(mydata)

执行'fix'命令时,您将看到此弹出框

然后您可以手动输入数据.这对于较小的示例而不是较大的示例是有效的.

  • ...然后`dput(mydata)` (18认同)

JT85.. 117

要快速创建dput数据,您只需将数据(一段)复制到剪贴板并在R中运行以下命令:

对于Excel中的数据:

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

对于txt文件中的数据:

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

sep如有必要,您可以更改后者.这只适用于您的数据当然在剪贴板中的情况.


BrodieG.. 112

指南:


制定问题的主要目的应该是让读者尽可能轻松地理解并在他们的系统上重现您的问题.为此:

  1. 提供输入数据
  2. 提供预期的产出
  3. 简洁地解释你的问题
    • 如果您有超过20行文本+代码,您可以返回并简化
    • 尽可能简化代码,同时保留问题/错误

这需要一些工作,但似乎是公平的权衡,因为你要求别人为你工作.

提供数据:


内置数据集

到目前为止,最好的选择是依靠内置数据集.这使得其他人可以轻松解决您的问题.型data()于R提示,看看数据是提供给您.一些经典的例子:

  • iris
  • mtcars
  • ggplot2::diamonds (外包装,但几乎每个人都有)

有关如何查找适合您的问题的数据集,请参阅此SO QA.

如果您能够重新解释您的问题以使用内置数据集,那么您更有可能获得良好的答案(和upvotes).

自生成数据

如果您的问题非常特定于现有数据集中未表示的数据类型,则提供R代码,该代码生成问题所体现的最小可能数据集.例如

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

现在有人试图回答我的问题,可以复制/粘贴这两行,并立即开始处理问题.

dput

作为最后的手段,您可以使用dput将数据对象转换为R代码(例如dput(myData)).我说作为"最后的手段",因为输出dput通常相当笨拙,复制粘贴很烦人,并且模糊了你的其余问题.

提供预期输出:


有人说过:

预期输出的图片价值1000字

- 一个非常聪明的人

如果您可以添加"我希望得到此结果"之类的内容:

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

对于你的问题,人们更有可能快速了解你想要做什么.如果您的预期结果很大且难以处理,那么您可能还没有充分考虑如何简化问题(参见下文).

简洁地解释你的问题


要做的主要是在提出问题之前尽可能地简化问题.重新构建问题以使用内置数据集将在这方面提供很多帮助.您还经常会发现,只需通过简化过程,您就可以回答自己的问题.

以下是一些好问题的例子:

在这两种情况下,用户的问题几乎肯定不是他们提供的简单示例.相反,他们抽象了他们问题的本质,并将其应用于一个简单的数据集来询问他们的问题.

为什么还有这个问题的另一个答案?


这个答案侧重于我认为最佳实践:使用内置数据集并以最小的形式提供您期望的结果.最突出的答案集中在其他方面.我不认为这个答案会突显出来; 这只是为了让我可以在对新手问题的评论中链接到它.


daniel.. 110

可重复的代码是获得帮助的关键.但是,有许多用户可能会怀疑甚至粘贴一大块数据.例如,他们可能正在处理敏感数据或收集用于研究论文的原始数据.出于任何原因,我认为在公开粘贴数据之前有一个方便的功能来"变形"我的数据会很好.anonymize包中的功能SciencesPo非常愚蠢,但对我来说它与dput功能很好地配合.

install.packages("SciencesPo")

dt <- data.frame(
    Z = sample(LETTERS,10),
    X = sample(1:10),
    Y = sample(c("yes", "no"), 10, replace = TRUE)
)

> dt
   Z  X   Y
1  D  8  no
2  T  1 yes
3  J  7  no
4  K  6  no
5  U  2  no
6  A 10 yes
7  Y  5  no
8  M  9 yes
9  X  4 yes
10 Z  3  no

然后我对它进行匿名化:

> 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

在应用匿名化和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


userJT.. 99

通常,您需要一些示例数据,但是,您不希望发布您的确切数据.要在已建立的库中使用某些现有data.frame,请使用data命令将其导入.

例如,

data(mtcars)

然后解决问题

names(mtcars)
your problem demostrated on the mtcars data set

  • 许多内置数据集(如流行的`mtcars`和`iris`数据集)实际上并不需要使用`data`调用. (13认同)

TMS.. 90

如果您有大型数据集无法轻松使用dput(),请将数据发布到pastebin并使用read.table以下命令加载它们:

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

灵感来自@Henrik.


Tyler Rinker.. 87

我正在开发wakefield软件包以满足快速共享可重复数据的需求,有时dput适用于较小的数据集,但我们处理的许多问题要大得多,共享如此大的数据集dput是不切实际的.

关于:

wakefield允许用户共享最少的代码来重现数据.用户设置n(行数)并指定任何数量的预设变量函数(目前有70个)模拟真实数据(性别,年龄,收入等)

安装:

目前(2015-06-11),wakefield是一个GitHub包,但最终会在编写单元测试后转到CRAN.要快速安装,请使用:

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

例:

这是一个例子:

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

这会产生:

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


talat.. 70

如果您factor希望数据中有一个或多个变量可以重复使用dput(head(mydata)),请考虑添加droplevels它,以便最小化数据集中不存在的因子级别不包含在dput输出中,以便使示例最小化:

dput(droplevels(head(mydata)))


CMichael.. 61

我想知道http://old.r-fiddle.org/链接是否是一个非常巧妙的分享问题的方式.它接收一个唯一的ID,甚至可以考虑将其嵌入到SO中.


user2100721.. 44

请不要粘贴您的控制台输出,如下所示:

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

我们不能直接复制粘贴它.

要使问题和答案正确重现,请尝试在发布之前删除+&>#输出以下输出和注释:

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

还有一件事,如果您使用了某个包中的任何函数,请提及该库.

  • @BCArg我手动删除`>`.但是,为了添加`#`,我在`RStudio`编辑器中使用`Ctrl + Shift + C`快捷键. (3认同)
  • 删除`&gt;`并手动添加`#`还是有自动的方法? (2认同)

小智.. 31

除了我发现非常有趣的所有上述答案之外,它有时可能非常容易,因为它在这里讨论: - 如何做一个最小的可重复的例子来获得R的帮助

制作随机向量的方法有很多种方法创建一个100数字向量,其中R中的随机值舍入为2位小数 或R中的随机矩阵

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

请注意,由于诸如尺寸等各种原因,有时很难共享给定数据.但是,当想要制作可重现的数据示例时,所有上述答案都很好并且非常重要.但请注意,为了使数据具有代表性(如果OP不能共享原始数据),最好用数据示例添加一些信息(如果我们调用数据mydf1)

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

此外,应该知道可以是数据结构的数据的类型,长度和属性

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


Andrii.. 31

你可以使用reprex来做到这一点.

正如mt1022所指出的那样,"...用于生产最小,可重复的例子的良好包装是"来自tidyverse的 " 代表 ".

根据Tidyverse的说法:

"reprex"的目标是以一种其他人可以运行它并感受到你的痛苦的方式打包你有问题的代码.

tidyverse网站上给出了一个例子.

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

我认为这是创建可重现示例的最简单方法.


TheRimalaya.. 27

以下是我的一些建议:

  • 尝试使用默认的R数据集
  • 如果您有自己的数据集,请将其包含在内dput,以便其他人可以更轻松地为您提供帮助
  • install.package()除非确实有必要,否则不要使用,如果您只是使用require或者,人们会理解library
  • 尽量简洁,

    • 有一些数据集
    • 尝试尽可能简单地描述您需要的输出
    • 在提出问题之前先自己动手
  • 上传图片很容易,如果有的话上传图表
  • 还包括您可能遇到的任何错误

所有这些都是可重复的例子的一部分.


dank.. 17

使用testthat包中的函数来显示您期望发生的内容是个好主意.因此,其他人可以更改您的代码,直到它运行没有错误.这减轻了那些想要帮助你的人的负担,因为这意味着他们不必解码你的文字描述.例如

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

比"我认为对于等于或超过10的x会出现1.23,否则为3.21,但我没有得到结果"更清楚.即使在这个愚蠢的例子中,我认为代码比单词更清晰.使用testthat让你的助手专注于代码,这可以节省时间,并为他们提供一种方式让他们知道他们已经解决了你的问题,然后再发布它


归档时间:

查看次数:

278830 次

最近记录:

11 月,3 周 前