LoginSignup
5

More than 5 years have passed since last update.

posted at

updated at

Organization

dplyr で DB 使うとき、テーブルをいちいち読み込むのめんどくさい #rstatsj

dplyr でデータベースからデータを取得したいとします。
その時、最初にやることはテーブルオブジェクトの生成です。

R
db <- src_sqlite("my_db.sqlite3")  # DB に接続
flights_tbl  <- tbl(db, "flights") # テーブルオブジェクトの生成

実際の DB でやってみましょう。
まずはテスト用 DB を作ります。

R
library(dplyr)
library(nycflights13) # テスト用データベースに入れるデータ

db <- src_sqlite("my_db.sqlite3", create = TRUE)
copy_nycflights13(db) # テスト用の SQLite データベースファイルを生成

作成したテスト用 DB に接続してみます。

R
db <- src_sqlite("my_db.sqlite3")
show(db)
結果
src:  sqlite 3.8.6 [my_db.sqlite3]
tbls: airlines, airports, flights, planes, sqlite_stat1, weather

この DB には 6個のテーブルが存在することがわかります。
これらのテーブルからデータを取得したい場合、それぞれのテーブルに対してテーブルオブジェクトを生成してやる必要があります。

R
airlines_tbl <- tbl(db, "airlines")
airports_tbl <- tbl(db, "airports")
flights_tbl  <- tbl(db, "flights")
planes_tbl   <- tbl(db, "planes")
weather_tbl  <- tbl(db, "weather")

これって面倒くさいと思いませんか?
よく見るとかなり定型的なコードです。

これを自動でやってくれる関数を書いてみましょう。

R
# DB の全てのテーブルに対してテーブルオブジェクトを生成する
load_tbls <- function(db, envir = parent.frame(), verbose = TRUE) {
  tbl_names <- dplyr::src_tbls(db)
  tbl_obj_names <- sprintf('%s_tbl', tbl_names)
  for(i in seq_along(tbl_obj_names)) {
    tbl_name <- tbl_names[i]
    tbl_obj_name <- tbl_obj_names[i]
    assign(tbl_obj_name, dplyr::tbl(db, tbl_name), envir = envir)
    if(verbose) cat(paste(sprintf("Creating %s ...\n", tbl_obj_name)))
  }
  invisible(NULL)
}

先ほど作ったテーブルオブジェクトを消しておきます。

R
rm(list = ls(pattern = "_tbl$"))
ls()
結果
[1] "db"        "load_tbls"

load_tbls() を実行してテーブルオブジェクトを生成してみましょう。

R
db <- src_sqlite("my_db.sqlite3")
load_tbls(db)
ls()
結果
[1] "airlines_tbl"     "airports_tbl"     "db"               "flights_tbl"      "load_tbls"        "planes_tbl"       "sqlite_stat1_tbl" "weather_tbl"

テーブルオブジェクトが自動生成されました。

以上です。

関連

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
5