Help us understand the problem. What is going on with this article?

htmltoolsパッケージでHTMLタグを生成する

More than 1 year has passed since last update.

R Markdownを利用していると,htmlタグをRのコードで生成できればと思うことがあるかと思います。ShinyのUIを作るときや,RmdでWebサイトを作成しているとこれが頻出します。そんな時はhtmltoolsパッケージが便利です。

htmltoolsにはRでhtmlなどのタグを生成するのに便利な関数がたくさん収められています。非常にたくさんの関数があるのですが,ドキュメントが整備されていなかったり内容が複雑だったりして,正直手探りな感じです。なので今回はあまり深追いせずに簡単なところだけ紹介します。

今回使うパッケージを読みこんどきます:

library(htmltools)
library(dplyr)
## 
## Attaching package: 'dplyr'

## The following objects are masked from 'package:stats':
## 
##     filter, lag

## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union

tagsリスト

tagshtmltoolsパッケージに格納されているリストで,以下のような要素が入っています:

names(tags)
##   [1] "a"           "abbr"        "address"     "area"        "article"    
##   [6] "aside"       "audio"       "b"           "base"        "bdi"        
##  [11] "bdo"         "blockquote"  "body"        "br"          "button"     
##  [16] "canvas"      "caption"     "cite"        "code"        "col"        
##  [21] "colgroup"    "command"     "data"        "datalist"    "dd"         
##  [26] "del"         "details"     "dfn"         "div"         "dl"         
##  [31] "dt"          "em"          "embed"       "eventsource" "fieldset"   
##  [36] "figcaption"  "figure"      "footer"      "form"        "h1"         
##  [41] "h2"          "h3"          "h4"          "h5"          "h6"         
##  [46] "head"        "header"      "hgroup"      "hr"          "html"       
##  [51] "i"           "iframe"      "img"         "input"       "ins"        
##  [56] "kbd"         "keygen"      "label"       "legend"      "li"         
##  [61] "link"        "mark"        "map"         "menu"        "meta"       
##  [66] "meter"       "nav"         "noscript"    "object"      "ol"         
##  [71] "optgroup"    "option"      "output"      "p"           "param"      
##  [76] "pre"         "progress"    "q"           "ruby"        "rp"         
##  [81] "rt"          "s"           "samp"        "script"      "section"    
##  [86] "select"      "small"       "source"      "span"        "strong"     
##  [91] "style"       "sub"         "summary"     "sup"         "table"      
##  [96] "tbody"       "td"          "textarea"    "tfoot"       "th"         
## [101] "thead"       "time"        "title"       "tr"          "track"      
## [106] "u"           "ul"          "var"         "video"       "wbr"

htmlに触れたことがある方は,この出力で察しがつくと思います。ひとつ出してみます:

tags$div
## function (...) 
## tag("div", list(...))
## <environment: namespace:htmltools>

ここに格納されているのはtag関数で,今回後ろに括弧をつけてなかったので関数のコードが出てきています。では引数を与えてみます:

kosaki <- tags$div(class = "section")

これで生成されたものをチェックします:

as.character(kosaki)
## [1] "<div class=\"section\"></div>"

引数に指定した属性が組み込まれたdivタグ生成されています。でもこれはただのcharacter型オブジェクトではなく,タグ用のオブジェクトになっています:

class(kosaki)
## [1] "shiny.tag"

なお,これのベースはlist型です:

is.list(kosaki)
## [1] TRUE

細かいところは省略します。

タグで挟みこむ要素を与える

pタグなどでは文字列を挟み込めないと意味がありません。もちろん可能です:

paragraph <- "終末何してますか?忙しいですか?救ってくれますか?"

tags$p(paragraph) %>% as.character()
## [1] "<p>終末何してますか?忙しいですか?救ってくれますか?</p>"

要するに,属性を指定せずにそのまま渡せばこんな感じで挟みこむようになります。

入れ子構造のhtmlを生成

tag関数を入れ子構造にするとうまくいきます:

kutori <- tags$div(id = "hoge",
         tags$h2("サブタイトル"),
         tags$p(paragraph),
         tags$ul(
           tags$li("箇条書き1"),
           tags$li("箇条書き2")
         )
         )
as.character(kutori) %>% cat()
## <div id="hoge">
##   <h2>サブタイトル</h2>
##   <p>終末何してますか?忙しいですか?救ってくれますか?</p>
##   <ul>
##     <li>箇条書き1</li>
##     <li>箇条書き2</li>
##   </ul>
## </div>

なお,この場合ですとkutoriをR Markdown内のRチャンクでそのまま出力させると,ちゃんとhtmlタグとして出力されてブラウザでhtmlとして読み込まれます。普通の文字列を生成するRコードで作ってしまうと,<code>タグで挟まれてしまうため,ブラウザでhtmlとして読み込まれません。これを解消するものだと考えてください。

応用例

htmlタグ生成をプログラミング

lapplymapplyを利用して,一気に生成することも可能です。なおtagList()はこれらtagによって生成されたオブジェクトをリストとしてまとめてくれるものです:

f_kutori <- function(title, list_c) {
  tagList(tags$h2(title),
          tags$ul(
            lapply(list_c, tags$li)
          )
  )
}

f_kutori("タイトル", c("終末何してますか?", "忙しいですか?", "救ってくれますか?")) %>% 
  as.character() %>%
  cat()
## <h2>タイトル</h2>
## <ul>
##   <li>終末何してますか?</li>
##   <li>忙しいですか?</li>
##   <li>救ってくれますか?</li>
## </ul>

このように,今まで慣れ親しんできたRの関数を絡めていくこともできます。また,htmlwidgets系は生成されたオブジェクトをそのままhtmlオブジェクトとして使えますので,うまく活用することもできます。

これらを駆使すれば,shinyやRmdによる表現力,および苦労が大きく変化します。ぜひ試してみてください。

Enjoy!

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away