7

是否有人知道在安装过程中从 Internet 下载数据集然后准备并保存它以便在使用加载包时可用的包library(packageName)?这种方法是否有任何缺点(除了如果数据源不可用或数据格式已更改,软件包安装将失败的明显缺点)?

编辑:一些背景。数据是 ZIP 存档中的三个制表符分隔文件,归联邦统计局所有,通常可免费访问。我有下载、提取和准备数据的 R 代码,最后创建了三个可以以.RData格式保存的数据帧。

我正在考虑创建两个包:提供数据的“数据”包和对其进行操作的“代码”包。

4

2 回答 2

3

我之前做过这个模型,当你发布你的编辑时。我认为它会起作用,但未经测试。我已经评论了它,所以你可以看到你需要改变什么。这里的想法是检查当前工作环境中是否有预期的对象。如果不是,请检查可以找到数据的文件是否在当前工作目录中。如果没有找到,提示用户下载文件,然后从那里继续。

myFunction <- function(this, that, dataset) {

  # We're giving the user a chance to specify the dataset.
  #   Maybe they have already downloaded it and saved it.
  if (is.null(dataset)) {

    # Check to see if the object is already in the workspace.
    # If it is not, check to see whether the .RData file that
    #   contains the object is in the current working directory.
    if (!exists("OBJECTNAME", where = 1)) {
      if (isTRUE(list.files(
        pattern = "^DATAFILE.RData$") == "DATAFILE.RData")) {
        load("DATAFILE.RData")

        # If neither of those are successful, prompt the user
        #   to download the dataset.
      } else {
        ans = readline(
          "DATAFILE.RData dataset not found in working directory.
          OBJECTNAME object not found in workspace. \n
          Download and load the dataset now? (y/n) ")
        if (ans != "y")
          return(invisible())

        # I usually use RCurl in case the URL is https
        require(RCurl)
        baseURL = c("http://some/base/url/")

        # Here, we actually download the data
        temp = getBinaryURL(paste0(baseURL, "DATAFILE.RData"))

        # Here we load the data
        load(rawConnection(temp), envir=.GlobalEnv)
        message("OBJECTNAME data downloaded from \n",
                paste0(baseURL, "DATAFILE.RData \n"), 
                "and added to your workspace\n\n")
        rm(temp, baseURL)
      }
    }
    dataset <- OBJECTNAME
  }
  TEMP <- dataset
  ## Other fun stuff with TEMP, this, and that.
}

两个包,托管在 Github

这是另一种方法,基于@juba 和 I 之间的评论。基本概念是,正如您所描述的,一个包用于代码,一个包用于数据。此函数将是包含您的代码的包的一部分。它会:

  1. 检查是否安装了数据包
  2. 检查您安装的数据包的版本是否与 Github 上的版本匹配,我们将假设它是最新版本。

当它未能通过任何检查时,它会询问用户是否要更新他们的软件包安装。在这种情况下,为了演示,我已经链接到我在 Github 上正在进行的一个包。这应该让您了解在您将其托管在您自己的包后需要替换什么才能使其与您自己的包一起使用。

CheckVersionFirst <- function() {
  # Check to see if installed
  if (!"StataDCTutils" %in% installed.packages()[, 1]) {
    Checks <- "Failed"
  } else {
    # Compare version numbers
    require(RCurl)
    temp <- getURL("https://raw.github.com/mrdwab/StataDCTutils/master/DESCRIPTION")
    CurrentVersion <- gsub("^\\s|\\s$", "", 
                           gsub(".*Version:(.*)\\nDate.*", "\\1", temp))
    if (packageVersion("StataDCTutils") == CurrentVersion) {
      Checks <- "Passed"
    }
    if (packageVersion("StataDCTutils") < CurrentVersion) {
      Checks <- "Failed"
    }
  }

  switch(
    Checks,
    Passed = { message("Everything looks OK! Proceeding!") },
    Failed = {
      ans = readline(
        "'StataDCTutils is either outdated or not installed. Update now? (y/n) ")
      if (ans != "y")
        return(invisible())
      require(devtools)
      install_github("StataDCTutils", "mrdwab")
    })
# Some cool things you want to do after you are sure the data is there
}

试试看CheckVersionFirst()

注意:只有当您虔诚地记得每次将新版本的数据推送到 Github 时都在描述文件中更新您的版本号时,这才会成功!

因此,为了澄清/概括/扩展,基本思想是:

  • 定期将数据包的更新版本推送到 Github,请务必在其文件中更改数据包的版本号。DESCRIPTION
  • 将此CheckVersionFirst()函数作为.onLoad事件集成到您的代码包中。(显然修改函数以匹配您的帐户和包名称)。
  • 更改读取的注释行# Some cool things you want to do after you are sure the data is there以反映您实际想要做的很酷的事情,这可能会从library(YOURDATAPACKAGE)加载数据开始......
于 2013-02-14T10:40:39.840 回答
1

这种方法可能效率不高,但却是一个很好的解决方法。如果您正在制作一个需要定期更新数据的包,请先制作一个包含该数据的包。它不需要任何函数,但我喜欢 setter 的概念(在这种情况下你可能不需要它)和 getter。

然后,当您制作包时,将“数据”包作为依赖项。这样,每当有人安装您的软件包时,他/她将始终拥有最新数据。

就您而言,您只需更换“数据”包中的数据,然后将其上传到您想要的存储库。

如果您不知道如何构建包,请检查?packages.skeletonR CMD CHECKR CMD BUILD

于 2013-02-14T10:03:29.767 回答