关于r faq:如何制作一个很好的R可重复的例子

How to make a great R reproducible example

在与同事讨论性能、教学、发送错误报告或搜索邮件列表和堆栈溢出的指导信息时,经常会要求提供一个可复制的示例,而且总是很有帮助的。

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

除了使用dput()dump()structure()之外,还有其他技巧吗?你什么时候应该包括library()require()报表?除了cdfdata等之外,还应避免哪些保留字?

一个人是如何做出一个伟大的或可重复的例子的?


最小可重复性示例包括以下各项:好的。

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

    重要提示:set.seed()的输出在r>3.6.0和以前的版本之间有所不同。请指定用于随机进程的R版本。好的。

    查看所用函数的帮助文件中的示例通常很有用。一般来说,这里给出的所有代码都满足最小可重复性示例的要求:提供数据,提供最小代码,并且所有内容都可以运行。好的。生成最小数据集

    对于大多数情况,只需为向量/数据帧提供一些值,就可以轻松地完成这项工作。或者您可以使用其中一个内置数据集,该数据集随大多数包一起提供。使用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(),例如:好的。

      1
      matrix(1:10, ncol = 2)

      可以使用data.frame()制作数据帧。应该注意数据框架中的条目名称,不要使其过于复杂。好的。

      一个例子:好的。

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

      对于某些问题,可能需要特定的格式。对于这些,可以使用任何提供的as.someType功能:as.factoras.Dateas.xts…。它们与向量和/或数据帧技巧结合在一起。好的。复制您的数据

      如果您有一些数据太难使用这些提示来构造,那么您可以使用例如head()subset()或索引来生成原始数据的子集。然后用dput()给我们一些可以立即放入r的东西:好的。

      1
      2
      3
      4
      5
      6
      7
      > 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")

      如果您的数据帧具有多个级别的因子,那么dput输出可能会很难处理,因为它仍然会列出所有可能的因子级别,即使它们不在您的数据子集中。为了解决这个问题,您可以使用droplevels()函数。请注意下面的物种是一个只有一个水平的因素:好的。

      1
      2
      3
      4
      5
      6
      7
      > 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")

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

      最坏情况下,您可以使用read.tabletext参数提供一个文本表示,可以读取该文本表示:好的。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      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还是其他什么方式),我们也应该提供这些应用程序的版本号,如果可能的话,还应该提供有关设置的必要信息。好的。

          如果您使用rstudioapi::versionInfo()在r studio中运行r,那么报告rstudio版本会很有帮助。好的。

          如果您对特定的包有问题,您可能希望通过提供packageVersion("name of the package")的输出来提供包的版本。好的。好啊。


          (以下是我的建议,从如何写一个可复制的例子。我试着把它变短,但很甜)

          如何编写可复制的示例。

          如果您提供一个可重复的例子,您很可能会得到关于R问题的很好的帮助。一个可复制的示例允许其他人通过复制和粘贴R代码来重新创建您的问题。

          为了使您的示例具有可复制性,您需要包括四件事情:必需的包、数据、代码和对R环境的描述。

          • 包应该加载在脚本的顶部,因此很容易看看这个例子需要哪些。

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

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

            • 确保您使用了空格并且变量名简洁,但是资料性的

            • 使用注释指示问题所在

            • 尽最大努力消除与问题无关的一切。代码越短,越容易理解。

            • 小精灵

            • 在代码的注释中包括EDOCX1[4]的输出。这总结了你的R环境,使您可以轻松检查是否使用过时的包裹。

            • 小精灵

              您可以通过启动一个新的R会话并将脚本粘贴到中来检查您是否真的创建了一个可复制的示例。

              在将所有代码放入电子邮件之前,考虑将其放到gist-github上。它将为您的代码提供良好的语法高亮显示,您不必担心电子邮件系统会损坏任何东西。


              就我个人而言,我更喜欢"一句话"。沿着这条线:

              1
              2
              3
              4
              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)时,我真的很感激。

              或者,可以切几个角并指向预先存在的数据集,例如:

              1
              2
              3
              library(vegan)
              data(varespec)
              ord <- metaMDS(varespec)

              别忘了提一下您可能使用的任何特殊软件包。

              如果你想在更大的物体上演示一些东西,你可以尝试

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

              如果您通过raster包处理空间数据,则可以生成一些随机数据。很多例子可以在包的小插曲中找到,但这里有一个小金块。

              1
              2
              3
              4
              5
              6
              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)获取一些数据集(请参见任务视图中的空间视图)。

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


              受这篇文章的启发,我现在使用了一个方便的函数当我需要发布到stackoverflow时。

              快速指示

              如果要复制的对象的名称是myData,请在r中运行以下命令:

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

              reproduce(myData)

              细节:

              此函数是dput的智能包装器,并执行以下操作:

              • 自动对大数据集采样(基于大小和类)。样品大小可调)
              • 创建dput输出
              • 允许您指定要导出的列
              • 附加到它的前面objName <- ...,以便它可以很容易地复制和粘贴,但是…
              • 如果在Mac上工作,输出会自动复制到剪贴板,这样您就可以简单地运行它,然后粘贴到您的问题上。
              • 小精灵可在此处获取源:

                • Github-发布/复制.r
                • 小精灵例子:

                  1
                  2
                  # 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行和一些特定的列进行抽样

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

                  。给出以下输出:

                  1
                  2
                  3
                  4
                  5
                  6
                  7
                  8
                  9
                  10
                  11
                  12
                  13
                  14
                  15
                  16
                  17
                  18
                  19
                  20
                  21
                  22
                  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==

                  还要注意,整个输出是在一个很好的单行,而不是一段很长的切碎行中。这样可以更容易地阅读问题文章,也更容易复制+粘贴。

                  2013年10月更新:

                  现在您可以指定将占用多少行文本输出(即,将粘贴到StackOverflow中的内容)。为此,使用lines.out=n参数。例子:

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

                  1
                  2
                  3
                  4
                  5
                  6
                  7
                  8
                  9
                  10
                  11
                  12
                  13
                      ==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==


                  以下是一个很好的指南:

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

                  但最重要的是:只要确保您编写了一小段代码,我们就可以运行它来查看问题所在。一个有用的函数是dput(),但是如果您有非常大的数据,您可能希望生成一个小的示例数据集,或者只使用前10行左右。

                  编辑:

                  还要确保您确定了问题所在。示例不应是带有"on line 200 there is an error"的完整R脚本。如果您使用R(我喜欢browser())和Google中的调试工具,那么您应该能够真正确定问题所在,并重现一个同样的错误的小例子。


                  R-HELP邮件列表有一个发布指南,其中包括提问和回答问题,包括生成数据的示例:

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

                  If I have a matrix x as follows:

                  1
                  2
                  3
                  4
                  5
                  6
                  7
                  8
                  9
                    > 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:

                  1
                  2
                  3
                    > x.df
                       row col value
                    1    A   x      1

                  ...
                  (To which the answer might be:

                  1
                  2
                  3
                    > 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")

                  )

                  单词small尤其重要。您应该瞄准一个可重复性最小的例子,这意味着数据和代码应该尽可能简单地解释这个问题。

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


                  由于R.2.14(我猜),您可以将数据文本表示直接输入read.table:

                  1
                  2
                  3
                  4
                  5
                  6
                  7
                  8
                  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
                  ")


                  有时候,无论你多么努力地尝试,这个问题都不能用较小的数据来重现,也不能用合成数据来重现(尽管展示如何生成没有重现问题的合成数据集是很有用的,因为它排除了一些假设)。

                  • 可能需要将数据发布到Web的某个地方并提供一个URL。
                  • 如果数据不能公开,但完全可以共享,那么您可以通过电子邮件将其发送给相关方(尽管这将减少麻烦处理数据的人数)。
                  • 实际上我还没有看到这样做,因为不能发布数据的人对发布任何形式的数据都很敏感,但在某些情况下,如果数据在某种程度上被充分匿名/混乱/损坏,人们仍然可以发布数据。
                  • 小精灵

                    如果你不能做到这一点,那么你可能需要聘请一名顾问来解决你的问题…

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

                    • 如何从私有数据创建示例数据集(用非格式化的占位符替换变量名和级别)?
                    • 给定从连续单变量分布中抽取的一组随机数,求出分布
                    • 小精灵


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

                      下面是一个可重复的例子,说明了要避免做什么(从一个真实的例子中,名字被改变以保护无辜者):

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

                      1
                      2
                      3
                      4
                      5
                      code
                      code
                      code
                      code
                      code (40 or so lines of it)

                      我怎样才能做到这一点?


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

                      1
                      2
                      3
                      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

                      然后您可以手动输入数据。这对于较小的例子比大的例子更有效。


                      要快速创建dput的数据,只需将(一段)数据复制到剪贴板,并在r中运行以下内容:

                      对于Excel中的数据:

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

                      对于TXT文件中的数据:

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

                      如有必要,可以在后者中更改sep。当然,只有当数据在剪贴板中时,这才有效。


                      指导方针:

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

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

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

                        提供数据:内置数据集

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

                        • 江户十一〔一〕号
                        • 埃多克斯1〔2〕
                        • ggplot2::diamonds(外部包装,但几乎每个人都有)
                        • 小精灵

                          有关如何查找适合您的问题的数据集,请参阅本手册。

                          如果您能够用内置的数据集来重新表述您的问题,那么您更有可能得到很好的答案(和升级投票)。

                          自生数据

                          如果您的问题非常特定于现有数据集中没有表示的数据类型,那么请提供R代码,该代码生成您的问题所显示的最小可能数据集。例如

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

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

                          DPT

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

                          提供预期输出:

                          有人曾经说过:

                          A picture of expected output is worth 1000 words

                          -- a very wise person

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

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

                          对于你的问题,人们更可能很快理解你想做什么。如果您期望的结果是大而难处理的,那么您可能还没有充分考虑如何简化您的问题(参见下一步)。

                          简洁地解释你的问题

                          要做的主要事情是在你问问题之前尽量简化你的问题。重新构建与内置数据集一起工作的问题将在这方面有很大帮助。你也会经常发现,通过简单化的过程,你会回答你自己的问题。

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

                          • 具有内置数据集
                          • 使用用户生成的数据
                          • 小精灵

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

                            为什么还要回答这个问题?

                            这个答案集中在我认为的最佳实践上:使用内置数据集并以最小的形式提供您期望的结果。最突出的答案集中在其他方面。我不希望这个答案会引起任何关注;这里只是为了让我能在评论中与新手问题联系起来。


                            可复制的代码是获得帮助的关键。然而,有许多用户可能对粘贴他们的数据的一部分持怀疑态度。例如,他们可以使用敏感数据,或者收集原始数据用于研究论文。不管出于什么原因,我认为在公开粘贴数据之前有一个方便的功能来"变形"我的数据是很好的。SciencesPo包中的anonymize函数非常愚蠢,但对我来说,它与dput函数很好地配合使用。

                            1
                            2
                            3
                            4
                            5
                            6
                            7
                            8
                            9
                            10
                            11
                            12
                            13
                            14
                            15
                            16
                            17
                            18
                            19
                            20
                            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

                            然后我匿名:

                            1
                            2
                            3
                            4
                            5
                            6
                            7
                            8
                            9
                            10
                            11
                            12
                            > 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命令之前,可能还需要对一些变量进行抽样,而不是对整个数据进行抽样。

                            1
                            2
                            3
                            4
                            5
                            6
                            7
                            8
                                # 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


                            通常情况下,您需要一些数据作为示例,但是,您不希望发布准确的数据。要在已建立的库中使用某些现有的data.frame,请使用data命令导入它。

                            例如。,

                            1
                            data(mtcars)

                            然后解决问题

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


                            如果有大数据集,使用dput()很难将其放到脚本中,将您的数据发布到Pastebin并使用read.table加载:

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

                            灵感来自@henrik。


                            我正在开发wakefield包来解决快速共享可复制数据的需要,有时对于较小的数据集,dput可以很好地工作,但我们处理的许多问题都要大得多,通过dput共享如此大的数据集是不现实的。

                            关于:

                            wakefield允许用户共享最少的代码来复制数据。用户设置n(行数),并指定模拟真实中频数据(如性别、年龄、收入等)的任意数量的预设变量函数(目前有70个)。

                            安装:

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

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

                            例子:

                            下面是一个例子:

                            1
                            2
                            3
                            4
                            5
                            6
                            7
                            8
                            9
                            10
                            11
                            r_data_frame(
                                n = 500,
                                id,
                                race,
                                age,
                                sex,
                                hour,
                                iq,
                                height,
                                died
                            )

                            这将产生:

                            1
                            2
                            3
                            4
                            5
                            6
                            7
                            8
                            9
                            10
                            11
                            12
                                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
                            .. ...   ... ...    ...      ... ...    ...   ...

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

                            1
                            dput(droplevels(head(mydata)))


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


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

                            1
                            2
                            3
                            4
                            5
                            6
                            7
                            8
                            9
                            10
                            11
                            12
                            13
                            14
                            15
                            16
                            17
                            18
                            19
                            20
                            21
                            22
                            23
                            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")
                            )

                            我们不能直接复制粘贴。

                            为了使问题和答案能够正确地重现,在发布之前尝试删除+&>,并将#用于输出和评论,如下所示:

                            1
                            2
                            3
                            4
                            5
                            6
                            7
                            8
                            9
                            10
                            11
                            12
                            13
                            14
                            15
                            16
                            17
                            18
                            19
                            20
                            21
                            22
                            23
                            #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")

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


                            除了以上所有我觉得很有趣的答案之外,有时会非常容易,正如这里所讨论的那样:-如何做一个最小的可重复的例子来获得有关r的帮助

                            有很多方法可以使随机向量创建一个100个数字的向量,其中r中的随机值四舍五入为2个小数,r中的随机矩阵

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

                            请注意,有时由于各种原因(如维度等),共享给定数据非常困难。但是,当您想创建一个可复制的数据示例时,上述所有答案都是非常重要的,并且非常重要。但请注意,为了使数据具有与原始数据相同的代表性(如果OP不能共享原始数据),最好在数据示例中添加一些信息,例如(如果我们将数据称为mydf1)

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

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

                            1
                            2
                            3
                            4
                            5
                            6
                            7
                            #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))

                            您可以使用Reprex来完成此操作。

                            如MT1022所述,"…产生最小的、可重复的例子的好包装是来自tidyverse的"reprex"。

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

                            在Tidyverse网站上给出了一个例子。

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

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


                            以下是我的一些建议:

                            • 尝试使用默认的R数据集
                            • 如果您有自己的数据集,请将它们与dput一起包含,这样其他数据集可以更轻松地帮助您
                            • 不要使用install.package(),除非确实有必要,否则人们会理解,如果你只是使用requirelibrary
                            • 尽量简明扼要,

                              • 有一些数据集
                              • 尽可能简单地描述您需要的输出
                              • 在你问问题之前自己动手
                              • 小精灵

                              • 上传图片很容易,所以如果你有,上传图片
                              • 还包括您可能有的任何错误
                              • 小精灵

                                所有这些都是可复制示例的一部分。


                                最好使用testthat包中的函数来显示您希望发生的事情。因此,其他人可以修改您的代码,直到它无错误地运行。这减轻了那些想帮助你的人的负担,因为这意味着他们不必解码你的文字描述。例如

                                1
                                2
                                3
                                4
                                5
                                6
                                7
                                library(testthat)
                                # code defining x and y
                                if (y >= 10) {
                                    expect_equal(x, 1.23)
                                } else {
                                    expect_equal(x, 3.21)
                                }

                                比"我认为x等于或超过10的y为1.23,否则为3.21,但我没有得到任何结果"更清楚。即使在这个愚蠢的例子中,我认为代码比单词更清晰。使用testthat可以让帮助者专注于代码,这节省了时间,而且它为他们提供了一种方法,让他们在发布之前知道他们已经解决了您的问题。