ほくそ笑む

R言語と統計解析について

RStudio Shiny TIPS

この記事は R Advent Calendar 2012 28日目の記事です。

はじめに

昨年に続き今年も R Advent Calendar に参加してみたのですが、ネタも時間もないので、最近注目している RStudio Shiny についての TIPS でも書こうかと思います。
Shiny を知らないという人は、前回の記事を読んでください。

1. plotOutput() の width と height に注意

出力ページに R のプロットを表示する plotOutput() 関数は引数 width と height でプロットのサイズを指定できます。
ただし、この width と height は CSS 属性であることに注意が必要です。
いつものノリで、width=500, height=500 などと打ってもプロットは表示されません。*1

plotOutput("plot", width=500, height=500) # これだとプロットが表示されない!

次のようにピクセルやパーセントで指定する必要があります。

plotOutput("plot", width="100%", height="400px")

また、height="100%" のように height をパーセント指定するとプロットが表示されなくなってしまいます。
これはなぜかというと、height のパーセント指定は親要素の高さに依存するからです*2
これを解決するには、下記のように書く必要があります。

mainPanel(
  plotOutput("plot", width="100%", height="100%"),
  tags$style(list("html,body,.container-fluid,.row-fluid:nth-child(2),.span8{height:100%;}"))
)

2. パッケージを使用したアプリの共有

Shiny を使えば R での解析結果を Web アプリ化して簡単に他人と共有できます。
ただし、解析にパッケージ(ライブラリ)を使用している場合、Shiny アプリを他の人に渡したとき、相手の R 環境にそのパッケージがインストールされていない場合はエラーとなり実行できません。
R ではほとんどの解析にパッケージを使用するため、これは大問題です。
この問題に対して、相手の環境に自動的にパッケージをインストールようなコードを書く方法が考えられます。
しかし、Windows だとデフォルトインストール場所へのアクセスに管理者権限が必要となるので失敗してしまいます。
もっとスマートな解決策は、パッケージごと相手に渡してしまうことです。
例えば、kohonen パッケージを使いたいときは、myLibrary というフォルダを作り、

install.packages("kohonen", lib="myLibrary")

のように lib 引数でインストール先のフォルダを指定します。
一方、ライブラリを呼び出す R のコードで

library("kohonen", lib.loc="myLibrary")

のように lib.loc 引数でライブラリ場所を指定すれば、ローカルフォルダからのライブラリの呼び出しが行えます。
相手に渡すときは、この myLibrary フォルダごと渡してしまえば、相手の環境にパッケージがインストールされていない場合にも Shiny アプリが動くようになります。やったね!
この実例として前回紹介した SOM of Iris が参考になると思います。

ちなみにこの方法は相手の OS が自分のと違う場合は問題ありなので注意してください。

3. fileInput() の使い方

まだ正式発表されていませんが、Shiny にはファイル入力 UI を作成する fileInput() 関数があります。*3

使い方はこんな感じです。

# ui.R
library(shiny)
shinyUI(pageWithSidebar(
  headerPanel(title="Input File Test"),  
  sidebarPanel(
    fileInput("file", label="Input File:")
  ),
  mainPanel(
    h4("File Information:"),
    verbatimTextOutput("info"),
    h4("Contents"),
    verbatimTextOutput("file")
  )
))
# server.R
library(shiny)
shinyServer(function(input, output) {
  output$info <- reactiveText(function(){
    file <- input$file
    if(is.null(file)) {
      "no data"
    } else {
      name <- paste("File Name: ", iconv(file$name, from="latin1", to="UTF-8"))
      size <- paste("File Size: ", file$size, "B")
      type <- paste("File Type: ", file$type)
      paste(name, size, type, sep="\n")
    }
  })
  output$file <- reactiveText(function() {
    file <- input$file
    if(is.null(file)) {
      "no data"
    } else {
      filepath <- file$datapath
      contents <- scan(file=filepath, what="character", sep="\n", encoding="UTF-8")
      paste(contents, collapse="\n")
    }
  }) 
})

この fileInput により、Shiny アプリにユーザデータを渡すことができるようになります。
ただし、私の個人的な意見としては、ユーザデータを渡さなければならないほどアプリが複雑になるのであれば、R ではなく他の言語で作った方がいいと思います。*4

Shiny はあくまで「解析結果を共有する」程度の軽い用途に使うことで威力を発揮すると思っています。

4. Shiny アプリを共有したい?それなら OpenShiny だ

というわけで Shiny は R での解析結果を共有したい場合に非常に強力なツールです。
ただし、結果を見たいだけの非プログラマにとっては、インストールや起動の手間があり難しいというのが問題です。
そこで、開発されたのが OpenShiny です。
OpenShiny は Shiny のインストール、アップデート、アプリの起動を自動的にやってくれる Windows アプリです。
詳しくはこちらをご覧ください。
Shiny アプリをワンクリックで起動するやつ作った - ほくそ笑む

5. RStudio Shiny でファイルごとにタブを作る

http://qiita.com/hoxo_m/items/69e825e8f2b59a9496d6

おわりに

Shiny を初めて触った時に「これは来る!」という予感がしました。
しかし、蓋を開けてみれば、今年の R Advent Calendar で Shiny 関係の記事は 0 です。
さびしいことです。
Shiny は JPEG を量産する運命にある雇われ解析人に、必ずや福音をもたらしてくれるでしょう。
そのために私はこれからも草の根的に Shiny についての情報発信をしていきたい所存であります。
以上です。

*1:エラーも出ません

*2:参照:http://loconet.web2.jp/blog/archives/2006/04/cssheight100.html

*3:まだベータ版だそうです。参照:https://groups.google.com/forum/#!msg/shiny-discuss/FWy0le9xVBE/WXSzuBLSKFUJ

*4:入力ファイルのフォーマットチェックを R でやりたいですか?私はイヤです。