Shiny
できれいなテーブルを作る際には DT (dataTable)パッケージを使うことが多いかと思います。
本日はこのDTで作ったテーブルをCSV
などで出力するためのダウンロードボタンの作り方についてです。
以下のようなイメージのダウンロードボタンとなります。
dataTableの基本コード
まずはDTによるテーブル出力の基本形から確認します。
Shiny
の公式ページにあるミニマムコードは以下の通りです。
組み込みデータmtcars
を使ったかなりさっぱりしたデータテーブルですね。
library(shiny) library(DT) ui <- basicPage( h2("The mtcars data"), DT::dataTableOutput("mytable") ) server <- function(input, output) { output$mytable = DT::renderDataTable({ mtcars }) } shinyApp(ui, server)
DTテーブルにダウンロードボタンをつける
ではこのミニマムサンプルを変更してテーブルデータをダウンロードする
ボタンをつけてみます。
変更点はDT::renderDataTable( )
の中身だけです。
今回のテーマであるダウンロードボタンを追加する際に必要な変更点は3つほどあります
extensions = 'Buttons'
の追加
ボタンをつける際に必要となるエクステンションの指定です。
dom = "B"
の指定
エクステンションでButtonの利用を追加しましたがoptions =
でdomに
B
を指定する必要があります。B以外でもDOMに指定している他のアルファベットを
変更するとテーブルに出てくるページネーションボタン、フィルターなどが変わります。
buttons =
で表示したいボタンを指定する
ここにあるもの以外にもcopy
やprint
などもあります。
library(shiny) library(DT) ui <- basicPage( h2("The mtcars data"), DT::dataTableOutput("mytable") ) server <- function(input, output) { output$mytable = DT::renderDataTable( mtcars, extensions = 'Buttons', options=list( dom="Blfrtip", buttons = c("csv", "excel", "pdf") ) ) # end of renderDataTable } shinyApp(ui, server)
ダウンロードボタンをかっこよく
上記の例ではボタンを3つ横並びにしましたが、まとめてプルダウン的に表示することができます。
以下の例を参考にしてください。この例ではcopy
のよこにDownload
ボタンが出現しており
そこをクリックするとcsvなどのフォーマットが選べる形になっています。
options=list( dom="Blfrtip", buttons = list("copy", list( extend = "collection", buttons = c("csv", "excel", "pdf"), text = "Download" ) ) )
ダウンロードボタンをさらに使いやすく
これまでのコードではダウンロードするさいにファイル名を入れる必要がありましたが、
デフォルトのファイル名をあらかじめ指定することも可能です。
以下の例を参考にファイルタイプ別にfilename
を指定すればOKです。
options=list( dom="Blfrtip", buttons = list("copy", list(extend = 'collection', buttons = list( list(extend='csv', filename = 'car-csv'), list(extend='excel', filename = 'car-xls') ), text = 'Download')) )
ダウンロード時のダウンロード件数が少ない件
これまでのコードはダウンロードボタンのカスタマイズについてですが、
実際にやってみるとダウンロドできる件数が少ないことに気づきます。
これは、DTテーブルは標準ではサーバー側でレンダリングが行われるので、
ダウンロードボタンは画面で出ている部分(UIで読み込んだ部分)しかデータのダウンロードが
できないためです。例えば、1ページあたり10行ずつ表示させているようなケースでは10行しか
ファイルに吐き出されません。
この回避のためには, server=FALSE
の指定を行って、UI側にレンダリングさせる必要があります。詳細は
ここ
を参照してください。
ただし、大きなテーブルの扱うのは負担が大きくなるため現実的ではありませんので
注意して使ってください。
output$mytable = DT::renderDataTable( mtcars, server = FALSE, extensions = 'Buttons', options=list( dom="Blfrtip", buttons = list("copy", list(extend = 'collection', buttons = list( list(extend='csv', filename = 'car-csv'), list(extend='excel', filename = 'car-xls') ), text = 'Download')) ) )
もう一つの方法は画面に出ている部分しか出力できなら「全件画面に出力してしまえば良いではないか」という
強引な方法もあります。
以下のサイトを参考に組み込んでみました。
出力件数を選べるプルダウンにALL
を入れた点がポイントです。ここでALL
を選んでダウンロードすれば
全件出力が可能となる(はずですが、大きなデータセットでは負担が大きすぎて無理筋かとは思いますが、、、)
options=list( dom="Blfrtip", buttons = list("copy", list(extend = 'collection', buttons = list( list(extend='csv', filename = 'car-csv'), list(extend='excel', filename = 'car-xls') ), text = 'Download')), lengthMenu = list( c(10, 20, -1) , c(10, 20, "All") ), pageLength = 10 )
結局
チョットした10行程度の推計結果のパラメータ出力などには簡便な手法で簡単に実装できるので
良いかと思いますが、大きなデータセットのダウンロードにはやはりdonwloadHandler
で実装するのが
王道かと思います。
このあたりはいろいろな手法が議論されていますので例えば以下をご参照ください。
おまけ
テーブルをいろいろカスタマイズできるdom
の指定ですが、ここの並び順変えるとテーブルに出力する位置を調整することができます。
この要素(アルファベット)の並び順が”概ね”表示の位置に反映されるということです。
ちなみにBlfrtip
をlfrtBip
とB(=button)
をt(=table)
の後ろにしてみるとボタンの位置がテーブルの下に変わります。
細かい調整をするためにはCSSを変更する必要ありますが軽めのレイアウトアレンジ程度ならこれでも
いけます。