Komputasi yang dapat direproduksi dalam R. Bagaimana memisahkan kode dan data?

Cukup sering ada kebutuhan untuk perhitungan berkala dan persiapan laporan konsolidasi tentang data swasembada. Itu menurut data yang disimpan sebagai file. Ini dapat berupa data yang dikumpulkan dari sumber terbuka, berbagai dokumen dan tabel excel, unduhan dari sistem perusahaan. Data mentah dapat memakan beberapa megabita atau beberapa gigabita. Data dapat didepersonalisasikan atau mengandung informasi rahasia. Dalam kasus ketika kode perhitungan ditempatkan di repositori, dan pekerjaan dilakukan oleh lebih dari satu orang di lebih dari satu komputer, masalah muncul dari menjaga konsistensi kode dan data. Pada saat yang sama, masih perlu untuk memastikan kepatuhan dengan hak akses yang berbeda terhadap kode dan data. Apa yang harus dilakukan?


Ini adalah kelanjutan dari publikasi sebelumnya .


RStudio sekarang secara aktif mengembangkan sebuah paket pinsuntuk menyelesaikan masalah ini. Sayangnya, solusi backend yang digunakan agak tidak populer dan mahal untuk digunakan di luasnya negara kita. AWS, Azure, Google cloud ... untuk setiap orang yang harus Anda bayar, untuk penyimpanan dan lalu lintas. AWS4 pinsbelum mendukung otentikasi , jadi cloud Yandex juga ada di sela-sela, meskipun tidak gratis.


Di sisi lain, tim analis yang mengerjakan tugas tertentu biasanya kecil (tidak lebih dari 5-10 orang). Banyak yang menggunakan Google drive, One drive, dll., Dalam format berbayar atau gratis. Mengapa tidak memanfaatkan sumber daya yang sudah diperoleh? Di bawah ini adalah salah satu alur kerja yang mungkin.


Rencana keseluruhan


  1. Perhitungan harus dilakukan secara lokal pada mesin, yang berarti bahwa mesin harus memiliki replika yang sebenarnya dari semua data yang diperlukan untuk perhitungan.
  2. Kode harus di bawah kontrol versi. Data tidak boleh jatuh ke dalamnya dengan cara apa pun (volume potensial dan kerahasiaan). Kami akan menyimpan replika data dalam folder terpisah dalam proyek (termasuk dalam .gitignore), atau dalam direktori eksternal relatif terhadap proyek.
  3. Master data akan disimpan oleh google drive. Kami menempatkan hak untuk mengakses direktori di dalamnya.

Itu tetap berlaku untuk kecil. Penting untuk mengimplementasikan fungsi sinkronisasi replika data lokal dengan cloud. Otorisasi dan otentikasi disediakan oleh google.


Di bawah ini adalah kode.


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

Berfungsi untuk sinkronisasi cache
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))
}

Tentukan pengenal folder di google drive sebagai jalur, Anda dapat mengambilnya dari bilah alamat browser. Pengidentifikasi akan tetap tidak berubah bahkan jika folder dipindahkan di drive.



Sederhana, kompak, nyaman, dan gratis.


Beberapa komentar


  1. Ada masalah dengan penyandian untuk gargleversi 0.4.0. Perlu memuat versi dev. Lebih detail di sini .
  2. Ada masalah dengan otorisasi pada RStudio Server "Tidak dapat mengotorisasi dari RStudio Server # 79 {Closed}" , tetapi ide untuk penyelesaiannya dapat ditemukan di sini .

Publikasi sebelumnya - “Pemrograman dan pohon Natal, dapatkah mereka digabungkan?” .

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


All Articles