簡體   English   中英

在安裝過程中從Internet下載數據的程序包

[英]Package that downloads data from the internet during installation

是否有人知道在安裝過程中從Internet下載數據集的包然后准備並保存它以便在使用library(packageName)加載包時可用? 這種方法是否有任何缺點(除了明顯的一個,如果數據源不可用或數據格式發生變化,軟件包安裝將失敗)?

編輯 :一些背景。 數據是ZIP存檔中的三個以制表符分隔的文件,由聯邦統計數據擁有,通常可以自由訪問。 我有R代碼下載,提取和准備數據,最后創建三個數據幀,可以保存為.RData格式。

我正在考慮創建兩個包:一個提供數據的“數據”包,以及一個對其進行操作的“代碼”包。

我之前做過這個模型,當你發布你的編輯時。 我認為它會起作用,但沒有經過測試。 我評論過它,你可以看到你需要改變什么。 這里的想法是檢查當前工作環境中是否有預期的對象。 如果不是,請檢查可以找到數據的文件是否在當前工作目錄中。 如果找不到,則提示用戶下載文件,然后從那里繼續。

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以反映您實際想要做的很酷的事情# Some cool things you want to do after you are sure the data is there ,這可能從library(YOURDATAPACKAGE)開始加載數據....

這種方法可能效率不高,但是一種很好的解決方法。 如果您正在制作需要定期更新數據的包,請首先制作包含該數據的包。 它不需要任何函數,但我喜歡setter的概念(在這種情況下你可能不需要)和getter。

然后在制作包時,將'data'包作為依賴項。 這樣,每當有人安裝您的包時,他/她將始終擁有最新數據。

您只需更換“數據”包中的數據,然后將其上傳到您想要的倉庫即可。

如果您不知道如何構建軟件包,請檢查?packages.skeletonR CMD CHECKR CMD BUILD

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM