LoginSignup
11
10

More than 5 years have passed since last update.

Shinyで複数のデータフレームを処理する手法を整理してみる

Last updated at Posted at 2016-07-05

個人的(?)にIOT開発で無敵だと考えているR/Shinyに関して、ちょっとしたコツみたいなものをつらつら書き残しておきたいと思います。

自分がつまずいたところがまず複数のデータフレームを1つのReactivityで処理するのにどう書いたら良いかというところです。実は何通りかあるようなのでこの記事ではそれの分類まで記載しておきます(完全動作サンプルは時間ができたら用意するのでしばらくお待ちください)。
※ちなみに以前は永続代入(グローバル変数)を使う方法も併記していましたが、Shiny-Serverで複数ユーザー同時使用時に他ユーザーのデータで上書きされる現象が見つかったため、そちらの記載は削除しました。多分同一インスタンス内でグローバル変数を使っているせいかなとは想像しています。

Reactivityとは

Shinyはフォームへの入力結果が勝手に画面に反応される動作がデフォルトになっています(乱暴な表現ですが、、)。それのスコープを定義しているのがReactivityという概念で、適切な区切りにしておかないと上手く動かないことがあります。詳しくはココ
http://shiny.rstudio.com/articles/reactivity-overview.html

データ読み込み方法の分類

eventReactive()で受けとる

actionButtonなどが押されたときに読み込む、という場合に有効です。Buttonを複数用意して異なるデータセットを異なるタイミングで読み込むことも可能です(例えばヘッダー情報を読み込むボタンでヘッダー一覧を読み込み、それの詳細が必要な場合は詳細読み込みボタンを押す、などのケースが考えられます)。

reload_head <- eventReactive(input$session_load, {
 #値を演算、複数DFの場合はリスト
 #リストで返す
  return(list(data1=data1,data2=data2))
 }
output$header_list <- renderTable({
 #リストの場合
  data <- reload_head()[["data1"]]
  data
})

reactive()でくくる

これは演算全体をreactiveにする場合に有効で、画面上で自動更新を実現させたい時などはこれを使うと良いです。

autoInvalidate <- reactiveTimer(15000) #再読み込みタイマーの設定
reload <- reactive({
#自動更新フラグがオンの時は自動更新させる
  if (input$auto_reload){
    autoInvalidate()
  }
  #値を演算、複数DFの場合はリスト
  return(list(data1=data1,data2=data2))
})
output$list <- renderTable({
  data <- reload_head()[["data1"]]
  data
})

reactiveValues()な変数を定義する

上記2つとほぼ同じことができるのですが、関数の返り値としての受け取りをする必要がなくなります。

tmp <- reactiveValues() #データ貯めるテンポラリバッファのリスト
observeEvent(input$reload, { #reloadボタンが押されたら、、
  #tmpリストに演算結果をセット
  tmp$data1_rv <- data1
  tmp$data2_rv <- data2
})
output$plot <- renderPlot({
  hist(tmp$data1_rv$Strength, breaks = 60, main = NULL)
})

11
10
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
11
10