dplyr: сбор данных из * многих * баз данных SQLite - PullRequest
0 голосов
/ 15 мая 2018

Ваши данные хранятся в большом количестве файлов базы данных SQLite.Вы хотели бы собрать данные из одной таблицы во всех этих файлах базы данных.

Возможно ли это с помощью dplyr или tidyverse?

Пример данных:

# Required Libraries
require('tidyverse')
require('RSQLite')
require('pool')
require('here')

# Create the dummy data
test <- data.frame(t(replicate(2,sample(0:10,4,rep=TRUE))))

fn <- here::here('1testing.sqlite3')
con <- dbPool(drv = RSQLite::SQLite(), 
              dbname = fn)
write_result = dbWriteTable(con, "TEST", test)
poolClose(con)
rm(con)

# Create multiple SQLite databases
fn = here::here('1testing.sqlite3')
file.copy(from=fn, to=here::here('2testing.sqlite3'))
file.copy(from=fn, to=here::here('3testing.sqlite3'))

ПРИМЕЧАНИЕ: В принятом ответе предлагается создать пользовательскую функцию (UDF).в этом вы можете объединять и обрабатывать данные из нескольких таблиц, возвращая конечный результат.

1 Ответ

0 голосов
/ 15 мая 2018

Это возможно.Ключевые части:

  1. Напишите функцию для хранения логики обработки БД.
  2. Используйте map в mutate, чтобы вызвать вашу пользовательскую функцию
  3. Преобразование имен файлов из факторов в строки.

Пример:

# Required libraries
require('tidyverse')
require('RSQLite')
require('pool')
require('here')

# User defined function to read+process the data
# Files that raise errors or warnings will have NA
gather_data <- function(fn) {
  dat = tryCatch({
          print(paste0('Processing ', fn))
          db <- dbPool(drv = RSQLite::SQLite(), dbname = fn)
          tblsmry <- db %>% tbl('TEST') %>% collect()
          tblsmry
        }, 
        error=function(e){print(e); return(as.data.frame(NA))},
        warning=function(e){print(e); return(as.data.frame(NA))},
        finally={
          if(exists('db') & db$valid ){ poolClose(db); rm(db) }
        }
      )
  if(exists('dat')){return(as.data.frame(dat))}else{return(as.data.frame(NA))}
}

# Collate the data
results <- data.frame( FILE = list.files(path = here::here(), pattern = '*testing.sqlite3$', full.names = FALSE) ) %>%
  mutate_if(is.factor, as.character) %>%
  mutate(res = map(FILE, gather_db_data)) %>%
  unnest()

Вывод:

> results
              FILE X1 X2 X3 X4
1 1testing.sqlite3  1  3  0  9
2 1testing.sqlite3  2  0  5  1
3 2testing.sqlite3  1  3  0  9
4 2testing.sqlite3  2  0  5  1
5 3testing.sqlite3  1  3  0  9
6 3testing.sqlite3  2  0  5  1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...