LoginSignup
7
5

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-03-27

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"

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

以上です。

関連

7
5
0

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
  3. You can use dark theme
What you can do with signing up
7
5