R中的可再现计算。如何分离代码和数据?

经常需要定期进行计算,并准备一份关于自给自足数据的综合报告。那些。根据存储为文件的数据。这可以是从开放源,各种文档和excel表中收集的数据,也可以是从公司系统中下载的数据。原始数据可能占用数兆字节或数千兆字节。数据可能被取消个性化或包含机密信息。在将计算代码放置在存储库中并且由多人在多于一台计算机上进行工作的情况下,会出现保持代码和数据一致性的问题。同时,仍然有必要确保遵守对代码和数据的不同访问权限。该怎么办?


它是以前出版物的延续


RStudio现在正在积极开发pins解决此问题的软件包不幸的是,在我们的广大国家/地区使用的后端解决方案在某种程度上并不受欢迎且昂贵。AWS,Azure,Google云……您需要为存储和流量支付的每一笔费用。AWS4 pins尚不支持身份验证,因此Yandex云虽然不是免费的,但也处于观望状态。


另一方面,从事特定任务的分析师团队通常很小(不超过5至10人)。许多使用付费或免费格式的Google驱动器,一个驱动器等。为什么不利用已经获得的资源呢?以下是可能的工作流程之一。


总体规划


  1. 计算应在计算机上本地执行,这意味着计算机必须具有计算所需的所有数据的实际副本。
  2. 该代码必须在版本控制下。数据不应以任何方式(潜在的数量和机密性)落入其中。我们将数据副本存储在项目中的单独文件夹中(包括中的.gitignore),或存储在相对于项目的外部目录中。
  3. 数据主数据将通过Google驱动器存储。我们在其中放置了访问目录的权利。

小型情况仍然如此。有必要实现本地数据副本与云的同步功能。授权和身份验证由Google提供。


下面是代码。


library(googledrive)
library(memoise)
#    google disk
drive_user()
updateGdCache(here::here("data/"), cloud_folder = "XXX___jZnIW3jdkbdxK0iazx7t63Dc")

缓存同步功能
updateGdCache <- function(local_folder, cloud_folder){
  #     
  cache_fname <- "gdrive_sig.Rds"
  # 0.  memoise     
  getGdriveFolder <- memoise(function(gdrive_folder){
    drive_ls(as_id(gdrive_folder), recursive = FALSE)
  })

  # 1.        
  cloud_gdrive_sig <- purrr::possibly(getGdriveFolder, NULL)(cloud_folder)
  #          ,     
  if(is.null(cloud_gdrive_sig)) {
    message("Some Google Drive issues happened. Can't update cache")
    return()
  }
  # 2.       
  fdir <- if(fs::is_dir(local_folder)) local_folder else fs::path_dir(local_folder)

  # 3.       
  local_files <- fs::dir_ls(fdir, recurse = FALSE) %>%
    fs::path_file()

  # 4.        
  local_gdrive_sig <- purrr::possibly(readRDS, NULL, quiet = TRUE)(fs::path(fdir, cache_fname))
  if(is.null(local_gdrive_sig)){
    #    ,   ,     
    #  ,   
    local_gdrive_sig <- cloud_gdrive_sig %>%
      dplyr::filter(row_number() == -1)
  }
  #         
  local_gdrive_sig <- local_gdrive_sig %>%
    dplyr::filter(name %in% local_files)

  # 5.      ,    ,   
  #  ,       
  reconcile_tbl <- cloud_gdrive_sig %>%
    dplyr::rename(drive_resource_cloud = drive_resource) %>%
    dplyr::left_join(local_gdrive_sig, by = c("name", "id")) %>%
    tidyr::hoist(drive_resource_cloud, cloud_modified_time = "modifiedTime") %>%
    tidyr::hoist(drive_resource, local_modified_time = "modifiedTime") %>%
    # TODO:   ,       
    #       = NA
    dplyr::mutate(not_in_sync = is.na(local_modified_time) | cloud_modified_time != local_modified_time)

  # 6.    
  syncFile <- function(fpath, id){
    res <- purrr::possibly(drive_download, otherwise = NULL)(as_id(id), path = fpath, overwrite = TRUE, verbose = TRUE)
    ifelse(is.null(res), FALSE, TRUE)
  }
  #  ,        ,   
  sync_gdrive_sig <- reconcile_tbl %>%
    dplyr::filter(not_in_sync == TRUE) %>%
    dplyr::mutate(fpath = fs::path(fdir, name)) %>%
    dplyr::mutate(sync_status = purrr::map2_lgl(fpath, id, syncFile)) %>%
    dplyr::select(name, id, sync_status)

  # 7.      ,   
  #   
  cloud_gdrive_sig %>%
    #   
    dplyr::anti_join(dplyr::filter(sync_gdrive_sig, sync_status == FALSE), by = c("name", "id")) %>%
    saveRDS(fs::path(fdir, cache_fname))
}

在Google驱动器中指定文件夹标识符作为路径,您可以从浏览器的地址栏中获取它。即使文件夹在驱动器中移动,标识符也将保持不变。



简单,紧凑,方便,免费。


几个评论


  1. gargle0.4.0版本的编码存在问题有必要加载开发版本。更多细节在这里
  2. RStudio服务器上的授权存在问题“无法从RStudio服务器#79 {关闭}进行授权”,但是可以在此处找到解决方法的想法

以前的出版物- “编程和圣诞树,可以结合使用吗?”

Source: https://habr.com/ru/post/undefined/


All Articles