在与同事讨论绩效、教学、发送错误报告或搜索邮件列表和Stack Overflow上的指导时,经常会询问一个可重复的示例,并且总是很有用。

你有什么建议来创建一个优秀的例子?如何以文本格式粘贴r中的数据结构?您还应包括哪些其他信息?

除了使用dput()、dump()或structure()之外,还有其他技巧吗?什么时候应该包含library()或require()语句?除了c、df、data等之外,应该避免哪些保留字。?

如何做出一个伟大的、可重复的例子?


当前回答

除了我发现非常有趣的上述所有答案之外,有时也很容易,正如这里所讨论的:如何制作一个最小的可重复示例来获得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))

其他回答

到目前为止,对于再现性部分,答案显然很好。这只是为了澄清,一个可复制的例子不能也不应该是问题的唯一组成部分。别忘了解释你希望它看起来是什么样子,以及你的问题的轮廓,而不仅仅是你迄今为止试图达到的目的。代码不够;你也需要语言。

这里有一个可重复的例子来说明应该避免做什么(从一个真实的例子中得出,为了保护无辜者而改变了名字):


以下是示例数据和我遇到问题的部分函数。

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

我怎样才能做到这一点?


这是一个很好的指南。

最重要的一点是:制作一小段代码,我们可以运行它来了解问题所在。一个有用的函数是dput(),但是如果您有非常大的数据,那么您可能需要制作一个小样本数据集,或者只使用前10行左右。

编辑:

此外,确保您确定了问题所在。示例不应该是一个完整的R脚本,其中包含“在第200行出现错误”。如果您使用R(我爱浏览器())和Google中的调试工具,那么您应该能够真正确定问题所在,并重现一个同样错误的小例子。

请不要像这样粘贴控制台输出:

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

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

您可以使用reprex执行此操作。

正如mt1022所指出的,“……生产最小、可重复示例的好包装是tidyverse的“reprex”。”。

根据Tidyverse的说法:

“reprex”的目标是以这样一种方式打包您的问题代码,使其他人可以运行它并感受到您的痛苦。

tidyverse网站上给出了一个示例。

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

我认为这是创建可复制示例的最简单方法。

指南:


你提出问题的主要目的应该是让读者尽可能容易地理解并在他们的系统上重现你的问题。为此:

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

这确实需要一些工作,但这似乎是一种公平的权衡,因为你要求别人为你做工作。

提供数据:


内置数据集

到目前为止,最好的选择是依赖内置数据集。这使得其他人很容易解决您的问题。在R提示符下键入data()以查看您可以使用的数据。一些经典的例子:

虹膜地铁车厢ggplot2::钻石(外包装,但几乎每个人都有)

检查内置数据集以找到适合您问题的数据集。

如果你能用内置的数据集重新表述你的问题,你就更有可能得到好的答案(和支持)。

自行生成的数据

如果您的问题是特定于现有数据集中未表示的数据类型,请提供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

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

简洁地解释您的问题


主要要做的是在提问之前尽可能简化问题。在这方面,重新构建问题框架以使用内置数据集将有很大帮助。你也会经常发现,仅仅通过简化的过程,你就能回答自己的问题。

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

内置数据集使用用户生成的数据

在这两种情况下,用户的问题几乎肯定与他们提供的简单示例无关。相反,他们抽象了问题的本质,并将其应用于一个简单的数据集,以提出问题。

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


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