如何做一个伟大的R可重现的例子?

在讨论与同事的表现,教学,发送错误报告或在邮件列表上寻找指导时,以及在这里,可复制的例子经常被问到,并且总是有帮助的。

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

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

一个人如何做出一个可重复的例子?


一个最小可重现的例子包含以下项目:

  • 一个最小的数据集,是重现错误所必需的
  • 重现错误所需的最小可运行代码,可以在给定数据集上运行。
  • 关于使用的软件包,R版本和运行的系统的必要信息。
  • 在随机过程的情况下,种子(由set.seed()设置)用于重现性
  • 查看使用函数的帮助文件中的示例通常很有帮助。 一般来说,所有给出的代码都满足最小可重现示例的要求:提供数据,提供最少代码,并且所有代码均可运行。

    生成最小数据集

    对于大多数情况,只需提供带有某些值的矢量/数据帧即可轻松完成此操作。 或者您可以使用大多数软件包提供的内置数据集之一。
    可以使用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()可以完成数据帧。 应该注意在数据框中输入条目的名称,而不要使其过于复杂。

    一个例子 :

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

    对于某些问题,可能需要特定的格式。 对于这些,可以使用任何提供的as.someType函数: as.factoras.Dateas.xts ,...这些与矢量和/或数据框架技巧结合使用。

    复制你的数据

    如果你有一些数据太难以使用这些技巧来构建,那么你总是可以使用head()subset()或索引来创建原始数据的subset() 。 然后使用例如。 dput()给我们一些可以立即放入R的东西:

    > 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()函数。 请注意以下物种是如何成为仅有一个等级的因素:

    > 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对象或分组tbl_df (类grouped_df从) dplyr 。 在这些情况下,您可以在共享之前转换回常规数据帧, dput(as.data.frame(my_data))

    在最坏的情况下,您可以使用read.tabletext参数来读取文本表示形式:

    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)
    

    生成最少的代码

    这应该是容易的部分,但通常不是。 你不应该做的是:

  • 添加所有类型的数据转换。 确保提供的数据已经是正确的格式(除非这是当然的问题)
  • 复制粘贴整个功能/块的代码,给出错误。 首先,尝试找出哪些行会导致错误。 通常你会发现你自己的问题。
  • 你应该做的是:

  • 如果您使用任何软件,请添加使用哪些软件包。
  • 如果打开连接或生成文件,请添加一些代码以关闭它们或删除文件(使用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 <-然后粘贴。
  • 花一点时间确保您的代码易于其他人阅读:

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

  • 用评论来表明你的问题在哪里

  • 尽力去除与问题无关的所有内容。
    代码越短越容易理解。

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

  • 你可以通过启动一个新的R会话并粘贴你的脚本来检查你是否已经创建了一个可重复使用的例子。

    在将所有代码放入电子邮件之前,请考虑将其放在Gist github上。 它会为你的代码提供很好的语法高亮显示,而且你不必担心电子邮件系统会造成任何问题。


    就个人而言,我更喜欢“一个”衬垫。 沿线的一些东西:

    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")
    
    链接地址: http://www.djcxy.com/p/623.html

    上一篇: How to make a great R reproducible example?

    下一篇: How do I correctly clone a JavaScript object?