RStudio Shiny チュートリアル レッスン2 ユーザーインターフェースを作ろう

> この記事は Shiny 公式サイトのチュートリアルを翻訳したものです。
> http://shiny.rstudio.com/tutorial/lesson2/

チュートリアル目次：http://d.hatena.ne.jp/hoxo_m/20151222/p1

# LESSON2 ユーザーインターフェースを作ろう

このレッスンでは、Shiny アプリのユーザーインターフェースの作り方を見ていきます。インターフェースのレイアウト法や、テキスト、画像、その他 HTML 要素の追加の仕方を学んでいきます。

それでは、[レッスン1](http://qiita.com/hoxo_m/items/c8365117f3444fb51df4)で作成した App-1 アプリを使って早速始めましょう。ui.R と server.R を開いて、次のように編集して下さい。

### ui.R

```r
shinyUI(fluidPage(
))
```

### server.R

```r
shinyServer(function(input, output) {
})
```

これが、Shiny アプリを作成するための最小コードです。起動すると、空のアプリが実行されます。スクラッチから Shiny アプリを作成する際の出発地点と言っていいでしょう。

## レイアウト

ui.R に記述されている `fluidPage` は、ブラウザ画面にフィットする UI を生成します。この `fluidPage` 関数に要素を配置することで、アプリのレイアウトを行います。例えば、ui.R を次のように変更すれば、タイトルパネル、サイドバーパネル、メインパネルの3つを持つインターフェースが作成されます。

```r
# ui.R

shinyUI(fluidPage(
  titlePanel("title panel"),

  sidebarLayout(
    sidebarPanel( "sidebar panel"),
    mainPanel("main panel")
  )
))
```
![sidebar-layout1.png](https://qiita-image-store.s3.amazonaws.com/0/2570/2f0d5c6a-f2b2-1e10-2a03-602481df54cb.png)

`sidebarLayout` 関数の2つの引数には常に同じものを渡します。`sidebarPanel` 関数の出力と、`mainPanel` 関数の出力です。これらの関数は、各パネルに要素を置くために使います。`sidebarLayout` 関数は、オプション引数 `position` を持ちます。`position = "right"` とすれば、サイドバーをアプリの右側に配置することができます。

```r
# ui.R

shinyUI(fluidPage(
  titlePanel("title panel"),

  sidebarLayout(position = "right",
    sidebarPanel( "sidebar panel"),
    mainPanel("main panel")
  )
))
```

![sidebar-layout2.png](https://qiita-image-store.s3.amazonaws.com/0/2570/2ab96775-d50f-1cb2-432b-a3ce815da248.png)

`titlePanel` と `sidebarLayout` は、`fluidPage` に追加する最もポピュラーな要素です。基本的に Shiny アプリにはサイドバーを付けます。しかし、`fluidRow` を使えば、レイアウトを完全にカスタマイズできます。`fluidRow` は、 low-level なグリッドシステムを使います。また、ナビゲーションバーを使った複数ページ UI にしたい場合は、`fluidPage` の代わりに `navbarPage` を使います。これらの高度なオプションに興味を持ったのなら、[Shiny Application Layout Guide](http://shiny.rstudio.com/articles/layout-guide.html)を読んで下さい。

## HTML 要素

Shiny アプリに要素を追加するためには、`*Panel` 関数の中で要素を配置します。例えば、上のアプリでは、文字列を各パネルに配置しました。より高度な要素を追加するためには、HTML タグ関数を使います。Shiny の HTML タグ関数の名前は、HTML5 タグ名と共通しています。いくつかを書き出してみましょう。

|Shiny関数|HTML5タグ|説明|
|:---------|:--------|:---|
|`p` 	|`<p>` 	|A paragraph of text|
|`h1` 	|`<h1>` 	|A first level header|
|`h2` 	|`<h2>` 	|A second level header|
|`h3` 	|`<h3>` 	|A third level header|
|`h4` 	|`<h4>` 	|A fourth level header|
|`h5` 	|`<h5>` 	|A fifth level header|
|`h6` 	|`<h6>` 	|A sixth level header|
|`a` 	|`<a>` 	|A hyper link|
|`br` 	|`<br>` 	|A line break (e.g. a blank line)|
|`div` 	|`<div>` 	|A division of text with a uniform style|
|`span` 	|`<span>` 	|An in-line division of text with a uniform style|
|`pre` 	|`<pre>` 	|Text ‘as is’ in a fixed width font|
|`code` 	|`<code>` 	|A formatted block of code|
|`img` 	|`<img>` 	|An image|
|`strong` 	|`<srtong>` 	|Bold text|
|`em` 	|`<em>` 	|Italicized text|
|`HTML` 	|  	|Directly passes a character string as HTML code|

## ヘッダー

ヘッダー要素を作成するために、ヘッダー関数を選んで、表示させたい文字を与えてみましょう。例えば、`h1("My title")` を実行すると、R コンソールは次のようになるでしょう。

```
> library(shiny)
> h1("My title")
<h1>My title</h1>
```

この要素をアプリに配置するためには、`h1("My title")` を、`titlePanel`、`sidebarPanel`、`mainPanel` の引数に入力します。すると、ウェブページの対応するパネルにテキストが表示されます。コンマで区切ることによって、複数の要素を同じパネルに表示することもできます。

やってみましょう。ui.R を次のように変更し、アプリを再起動させてください(例えば、`runApp("App-1")`)

```r
# ui.R

shinyUI(fluidPage(
  titlePanel("My Shiny App"),
  sidebarLayout(
    sidebarPanel(),
    mainPanel(
      h1("First level title"),
      h2("Second level title"),
      h3("Third level title"),
      h4("Fourth level title"),
      h5("Fifth level title"),
      h6("Sixth level title")
    )
  )
))
```
これで、アプリはこんな風になったはずです。
![headers.png](https://qiita-image-store.s3.amazonaws.com/0/2570/e81ba0a6-c8e7-b9a9-12a4-6109338dc096.png)
もし、ジョージ・ルーカスが最初のアプリを作ったら、こんな風になるかも。
![lucas.png](https://qiita-image-store.s3.amazonaws.com/0/2570/58d305bf-2a83-c31e-4770-955b31248f58.png)
この効果は `align = "center"` を入れることによってできます。Shiny のタグ関数は、HTML 属性を追加することが可能なのです。例えば、`h6("Episode IV", align = "center")` のようにします。もし、HTML 属性についてあまり知らないなら、[w3schools](http://www.w3schools.com/tags/tag_hn.asp) のようなサイトを参照して下さい。他にもオンライン上にはたくさんのリソースを見つけることができます。

ちなみに、上の UI を作るコードは以下です。

```r
# ui.R

shinyUI(fluidPage(
  titlePanel("My Shiny App"),
  sidebarLayout(
    sidebarPanel(),
    mainPanel(
        h6("Episode IV", align = "center"),
        h6("A NEW HOPE", align = "center"),
        h5("It is a period of civil war.", align = "center"),
        h4("Rebel spaceships, striking", align = "center"),
        h3("from a hidden base, have won", align = "center"),
        h2("their first victory against the", align = "center"),
        h1("evil Galactic Empire.")
    )
  )
))
```

## 書式付きテキスト

Shiny のタグ関数の中には、書式付きテキストに対応するものがたくさんあります。これは、例を見ると分かりやすいと思います。ui.R に次のコードを貼りつけて保存して下さい。もし、Shiny アプリを起動したままにしているのなら、リロードすることで変更を反映させることができます。もしアプリを停止しているのなら、再起動させて下さい。

更新されたアプリと、ui.R を見比べることで、書式付きテキストについて知ることができるでしょう。

```r
# ui.R

shinyUI(fluidPage(
  titlePanel("My Shiny App"),
  sidebarLayout(
    sidebarPanel(),
    mainPanel(
      p("p creates a paragraph of text. This paragraph is followed by br(), which makes a blank line."),
      p("When you want to start a new paragraph, just use a new p() command. If you supply a style attribute, you can change the format of the entire paragraph", style = "font-family: 'times'; font-size: 16pt"),
      strong("Strong() makes bold text."),
      em("And em() makes italicized (i.e, emphasized) text."),
      br(),
      code("code displays your text like computer code"),
      div("Use span and div to create segments of text that all have a similar style. For example, this division of text is all blue because I passed the argument 'style = color:blue' to div", style = "color:blue"),
      br(),
      p("span does the same thing, but it works with",
        span("groups of words", style = "color:blue"),
        "that appear inside a paragraph.")
    )
  )
))
```

+ p はパラグラフを作ります。パラグラフは空行 br() を伴います。
+ 新しいパラグラフを始めたいときは、単に p() を使います。style 属性を与えると、パラグラフ全体の書式を変更できます。
+ strong() は太字になります。
+ em() はイタリックになります(すなわち強調(emphasized))。
+ code はプログラムコードのように表示されます。
+ span と div は同じスタイルを持つ領域を作成します。例えば、この div は 'style = color:blue' を指定しているので全てのテキストが青になります。
+ span も同様です。ただし、span はパラグラフの内部で使います。

![formatting.png](https://qiita-image-store.s3.amazonaws.com/0/2570/500a828b-c503-6412-5e6a-9899cafef307.png)

## 画像

`img` 関数は、アプリに画像を挿入します。画像ファイル名を `src` 引数に与えて下さい。`img` 関数は HTML タグを出力するため、`src` 引数には `<img>` タグの `src` 属性と同じものを与える必要があります。また、`height` や `width` のように、他の HTML 属性を含めることもできます。`height` と `width` はピクセル数で指定することに注意して下さい。

```r
img(src = "my_image.png", height = 72, width = 72)
```

`img` 関数は画像ファイルを特別な場所から探します。画像ファイルは ui.R ファイルと同じディレクトリに作られた www フォルダに配置しなければなりません。例えばもし、[bigorb.png](http://shiny.rstudio.com/tutorial/lesson2/www/bigorb.png) という画像ファイルを使いたかったら、`App-1` フォルダは次のようになります。
![bigorb2.png](https://qiita-image-store.s3.amazonaws.com/0/2570/e4def582-a0fc-3b2a-7735-d009bbaf3ced.png)
このように配置して、下記の ui.R でアプリを作ってみましょう。bigorb.png ファイルは[ここ](http://shiny.rstudio.com/tutorial/lesson2/www/bigorb.png)からダウンロードできます。

```r
# ui.R

shinyUI(fluidPage(
  titlePanel("My Shiny App"),
  sidebarLayout(
    sidebarPanel(),
    mainPanel(
      img(src="bigorb.png", height = 400, width = 400)
    )
  )
))
```

![bigorb1.png](https://qiita-image-store.s3.amazonaws.com/0/2570/b435b123-8f94-9e42-c0cb-192ad9fdd5da.png)

## やってみよう

このレッスンで説明した関数を使えば、非常に魅力的な UI が作れるはずです。下に示すアプリを作成することで、これらの関数をよく理解できるようになるでしょう。解答は[公式サイト](http://shiny.rstudio.com/tutorial/lesson2/)にありますが、答え合わせのために使うだけにして、コピペなどせずにスクラッチから自分で書いてみましょう。
![my-shiny-app.png](https://qiita-image-store.s3.amazonaws.com/0/2570/7321c76a-76e9-69b2-b6ff-668295e3e23d.png)

## まとめ

Shiny アプリの UI のレイアウト法と、シンプルな HTML 要素を使う方法を学びました。これにより、

+ UI を `fluidPage`、`titlePanel`、`sidebarLayout` で作る
+ Shiny のタグ関数を使って、HTML 要素を作る
+ タグ関数の引数を使って、HTML 要素の属性を指定する
+ `titlePanel`、`sidebarPanel`、`mainPanel` にタグ関数の出力を渡すことで、HTML 要素を追加する
+ コンマで区切ることで、各パネルには複数の要素を追加する
+ www フォルダに画像ファイルを置くことで、img 関数によって Shiny アプリに画像を追加する

ということができるようになりました。

シンプルな要素を追加できるようになったので、次はもっと複雑な要素、つまり、ウィジェットを追加する方法を学びましょう。ウィジェットは、インタラクティブなウェブ要素であり、ユーザーがアプリを操作するのに使われます。

それでは、[レッスン3](http://qiita.com/hoxo_m/items/8e84eb67c44afebe4d24)に進みましょう。

- [レッスン3 - コントロールウィジェットを追加しよう](http://qiita.com/hoxo_m/items/8e84eb67c44afebe4d24)
- [チュートリアル目次へ戻る](http://d.hatena.ne.jp/hoxo_m/20151222/p1)