Reproduzierbares Rechnen in R. Wie trenne ich Code und Daten?

Sehr oft sind regelmäßige Berechnungen und die Erstellung eines konsolidierten Berichts über autarke Daten erforderlich. Jene. nach Daten, die als Dateien gespeichert sind. Dies können Daten sein, die aus Open Source, verschiedenen Dokumenten und Excel-Tabellen, Downloads von Unternehmenssystemen gesammelt wurden. Rohdaten können mehrere Megabyte oder mehrere Gigabyte aufnehmen. Daten können entpersönlicht sein oder vertrauliche Informationen enthalten. In dem Fall, in dem der Berechnungscode im Repository abgelegt wird und die Arbeit von mehr als einer Person auf mehr als einem Computer ausgeführt wird, tritt das Problem auf, die Konsistenz des Codes und der Daten aufrechtzuerhalten. Gleichzeitig ist es weiterhin erforderlich, die Einhaltung unterschiedlicher Zugriffsrechte auf den Code und die Daten sicherzustellen. Was zu tun ist?


Es ist eine Fortsetzung früherer Veröffentlichungen .


RStudio entwickelt derzeit aktiv ein Paket pins, um dieses Problem zu lösen. Leider sind die verwendeten Backend-Lösungen in der Weite unseres Landes etwas unpopulär und teuer. AWS, Azure, Google Cloud ... für jeden, den Sie bezahlen müssen, für Speicher und Datenverkehr. AWS4 pinsunterstützt die Authentifizierung noch nicht, daher steht die Yandex-Cloud ebenfalls am Rande, obwohl sie nicht kostenlos ist.


Auf der anderen Seite sind Analystenteams, die an bestimmten Aufgaben arbeiten, normalerweise klein (nicht mehr als 5-10 Personen). Viele verwenden Google Drive, One Drive usw. in einem kostenpflichtigen oder kostenlosen Format. Warum nicht bereits erworbene Ressourcen nutzen? Unten finden Sie einen der möglichen Workflows.


Gesamtplan


  1. Die Berechnungen sollten lokal auf der Maschine durchgeführt werden. Dies bedeutet, dass die Maschine über eine tatsächliche Kopie aller für die Berechnungen erforderlichen Daten verfügen muss.
  2. Der Code muss unter Versionskontrolle stehen. Daten sollten in keiner Weise dorthin gelangen (potenzielles Volumen und Vertraulichkeit). Wir speichern das Datenreplikat entweder in einem separaten Ordner im Projekt (einschließlich in .gitignore) oder in einem externen Verzeichnis relativ zum Projekt.
  3. Der Datenmaster wird von Google Drive gespeichert. Wir platzieren die Rechte für den Zugriff auf Verzeichnisse darin.

Es bleibt der Fall für kleine. Es ist erforderlich, die Synchronisierungsfunktion des lokalen Datenreplikats mit der Cloud zu implementieren. Die Autorisierung und Authentifizierung erfolgt durch Google.


Unten ist der Code.


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

Funktion zur Cache-Synchronisation
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))
}

Geben Sie die Ordner-ID in Google Drive als Pfad an. Sie können sie aus der Adressleiste des Browsers entnehmen. Die Kennung bleibt auch dann unverändert, wenn der Ordner auf dem Laufwerk verschoben wird.



Einfach, kompakt, bequem und kostenlos.


Einige Kommentare


  1. Es gibt Probleme mit der Codierung für die gargleVersion 0.4.0. Es ist notwendig, die Dev-Version zu laden. Weitere Details hier .
  2. Es gibt Probleme mit der Autorisierung auf RStudio Server "Autorisierung von RStudio Server # 79 {Closed} nicht möglich" , aber Ideen für eine Problemumgehung finden Sie hier .

Vorherige Veröffentlichung - "Programmierung und Weihnachtsbaum, können sie kombiniert werden?" .

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


All Articles