在安装过程中从Internet下载数据的程序包

时间:2013-02-14 09:42:13

标签: r packaging

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

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

我正在考虑创建两个包:一个提供数据的“数据”包,以及一个在其上运行的“代码”包。

2 个答案:

答案 0 :(得分: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上的版本匹配,我们将假设该版本是最新版本。
  3. 如果任何检查失败,它会询问用户是否要更新其软件包的安装。在这种情况下,为了演示,我已经链接到我在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,确保更改 数据的版本号 < / strong>在您DESCRIPTION文件中打包时。
    • 将此CheckVersionFirst()功能整合为 代码 包中的.onLoad事件。 (显然修改功能以匹配您的帐户和包名称。)
    • 更改标有# Some cool things you want to do after you are sure the data is there的注释行,以反映您真正想要做的很酷的事情,这可能从library(YOURDATAPACKAGE)开始加载数据....

答案 1 :(得分:1)

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

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

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

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