Rで解析:動的なHTMLレポートを作成するhtmlreportRパッケージ
解析結果をまとめたHTMLレポートは、表の並べ替えや絞り込みといった操作ができると、受け取った側が自分の関心に沿って中身を確かめられます。しかし、Rの出力からこうしたレポートを組み立てるには、JavaScriptやCSSの記述と、データの受け渡しの両方に手間がかかります。
「htmlreportR」パッケージは、テンプレートに書いた見出しとコマンドから動的なHTMLレポートを組み立てるためのパッケージです。データフレームを渡すだけで並べ替えや検索、ファイル出力に対応した表を作成でき、独自のJavaScriptやCSS、CDNの読み込みも指定できます。また、ワイルドカードを含むパスの展開や、見出し行・列の入れ替え、階層構造を持つHTMLリストへの変換など、レポートの中身を整えるためのコマンドも収録されています。本パッケージの利用で、静的なプロットだけでは伝えきれない結果を、動きのあるHTMLレポートとしてまとめられるのではないかと考えます。
パッケージバージョンは2.0.1。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。
<おすすめのRに関する書籍です>
パッケージのインストール
下記コマンドを実行してください。
# パッケージのインストール
install.packages("htmlreportR")
# パッケージの読み込み
library("htmlreportR")
<おすすめのRに関する書籍です>
コマンド例
詳細はコメント、パッケージのヘルプを確認してください。
HTMLはハイパーテキストマークアップ言語、JSはJavaScript、CSSはCascading Style Sheetsの略称で、いずれもWebページを構成するための標準的な技術です。
本パッケージのレポートは、HTMLとRのコードを並べて書いたテンプレートを用意し、そこにデータを流し込んで組み立てます。はじめにレポート本体を作成するコマンドを確認し、その後にレポートの中身を整えるコマンドを確認します。
動的HTMLレポートの作成:htmlReportコマンド
レポートの土台となる参照クラスです。newメソッドでレポートオブジェクトを作成し、buildメソッドでテンプレートを読み込んで本体を組み立て、write_reportメソッドでHTMLファイルとして書き出します。containerオプションに渡したデータは、テンプレートの中でplotterという名前のレポートオブジェクトを通して参照します。
テンプレートに書くRのコードは、knitrのHTML用の記法である「<!–begin.rcode」から「end.rcode–>」までの範囲に記述します。
| オプション | 意味 | 初期値 |
|---|---|---|
| container | レポートから参照するデータフレームなどをまとめた名前付きリスト | list() |
| title_doc | レポートのタイトル | “” |
| type_index | 見出し索引の形式、”contents_list”または”menu” | “contents_list” |
| tmp_folder | 作業用の一時フォルダのパス、書き出し後に削除される | tempdir(check = TRUE) |
| src | パッケージの付属ファイルを格納したフォルダのパス | find.package(“htmlreportR”) |
| compress_obj | 埋め込むオブジェクトを圧縮するかの論理値 | TRUE |
| files_css | 追加で読み込む独自CSSファイルのパス、カンマ区切りで複数指定可 | NULL |
| files_js | 追加で読み込む独自JavaScriptファイルのパス、カンマ区切りで複数指定可 | NULL |
| cdn_js | CDNから読み込むJavaScriptのURL、カンマ区切りで複数指定可 | NULL |
| cdn_css | CDNから読み込むCSSのURL、カンマ区切りで複数指定可 | NULL |
テンプレートの中では、レポートオブジェクトの各メソッドを呼び出して中身を作成します。主なメソッドは下記のとおりです。
| メソッド | 意味 |
|---|---|
| build | テンプレートを読み込みレポートの本体を組み立てる |
| write_report | 組み立てたレポートをHTMLファイルとして書き出す |
| table | データフレームをHTMLの表に変換する |
| heatmap | データフレームをヒートマップとして描画する |
| barplot | データフレームを棒グラフとして描画する |
| line | データフレームを折れ線グラフとして描画する |
| boxplot | データフレームを箱ひげ図として描画する |
| density | データフレームを密度プロットとして描画する |
| scatter2D | データフレームを散布図として描画する |
| static_plot_main | 任意の作図関数の結果を画像としてレポートに埋め込む |
| static_ggplot_main | ggplot2による作図結果を画像としてレポートに埋め込む |
| embed_img | 画像ファイルをレポートに埋め込む |
| mermaid_chart | Mermaid記法で書いた図をレポートに埋め込む |
| prettify_div | 要素を囲む領域の体裁を整える |
| create_title | 見出しを作成し索引に登録する |
# 宇治茶の生産量データを、1行目に見出しを含む形で作成
cha <- data.frame(
V1 = c("地区", "宇治", "宇治田原", "和束"),
V2 = c("生産量_kg", "1200", "950", "800"),
V3 = c("面積_ha", "15", "12", "10"),
stringsAsFactors = FALSE
)
# レポートから参照するオブジェクトをコンテナにまとめる
container <- list(ujicha = cha)
# テンプレートを作成、tableメソッドで動的な表を作成する
template <- c(
"<h1>宇治茶の産地レポート</h1>",
"<!--begin.rcode ujicha_table",
"cat(plotter$table(list(id = \"ujicha\", header = TRUE, text = \"dynamic\",",
" table_rownames = FALSE, styled = \"dt\")))",
"end.rcode-->"
)
# テンプレートをファイルとして保存
writeLines(template, "ujicha_template.txt")
# レポートオブジェクトを作成
plotter <- htmlReport$new(container = container,
title_doc = "宇治茶の産地レポート",
tmp_folder = "tmp_ujicha")
# テンプレートを読み込みレポートを組み立てる
plotter$build("ujicha_template.txt")
# HTMLファイルとして書き出す
plotter$write_report("ujicha_report.html")
# 出力されたファイルを確認
file.exists("ujicha_report.html")
[1] TRUEtableメソッドのstyledオプションに”dt”を指定すると、並べ替えや検索、コピーやCSV・Excel形式での書き出しができる動的な表になります。headerオプションにTRUEを指定した場合は、データの1行目が見出しとして扱われます。
スクリプトモードでのレポート作成:main_htmlreportRコマンド
ファイルの読み込みからHTMLの書き出しまでを一括で行います。データファイルとテンプレートの場所を設定リストにまとめて渡すだけで、レポートオブジェクトの作成から書き出しまでが内部で実行されます。
| オプション | 意味 | 初期値 |
|---|---|---|
| options | レポートの作成に必要な要素をまとめたリスト | なし |
optionsに指定できる主な要素は下記のとおりです。初期値は、パッケージに付属するスクリプトhtml_report.Rで設定される値です。
| 要素 | 意味 | 初期値 |
|---|---|---|
| data_files | 読み込むタブ区切りファイルのパス、カンマ区切りで複数指定可 | NULL |
| template | 読み込むテンプレートファイルのパス | NULL |
| output_file | 書き出すHTMLファイルのパス、未指定時はテンプレートと同じ場所のreport.html | NULL |
| title | レポートのタイトル | “htmlreportR” |
| source_folder | パッケージの付属ファイルを格納したフォルダのパス | なし |
| uncompressed_data | compress_objに渡される論理値、TRUEで埋め込むオブジェクトを圧縮 | TRUE |
| css_files | 追加で読み込む独自CSSファイルのパス、カンマ区切りで複数指定可 | NULL |
| js_files | 追加で読み込む独自JavaScriptファイルのパス、カンマ区切りで複数指定可 | NULL |
| css_cdn | CDNから読み込むCSSのURL、カンマ区切りで複数指定可 | NULL |
| js_cdn | CDNから読み込むJavaScriptのURL、カンマ区切りで複数指定可 | NULL |
| menu | 見出し索引の形式、”contents_list”または”menu” | “contents_list” |
# 作業用のフォルダを作成
dir.create("kyoto_script", showWarnings = FALSE)
# 京野菜の出荷量データを作成
yasai <- data.frame(
品目 = c("九条ねぎ", "賀茂なす", "万願寺とうがらし"),
出荷量_kg = c(480, 320, 210)
)
# タブ区切りのテキストファイルとして保存
write.table(yasai, file.path("kyoto_script", "yasai.txt"),
sep = "\t", quote = FALSE, row.names = FALSE)
# テンプレートを作成、idには読み込むファイル名を指定
template <- c(
"<h1>京野菜の出荷量</h1>",
"<!--begin.rcode yasai_table",
"cat(plotter$table(list(id = \"yasai.txt\", header = TRUE, text = \"dynamic\",",
" table_rownames = FALSE, styled = \"dt\")))",
"end.rcode-->"
)
# テンプレートをファイルとして保存
writeLines(template, file.path("kyoto_script", "template.txt"))
# レポートの作成に必要な設定をリストにまとめる
opt <- list(
data_files = file.path("kyoto_script", "yasai.txt"),
template = file.path("kyoto_script", "template.txt"),
output_file = file.path("kyoto_script", "kyoyasai_report.html"),
title = "京野菜の出荷量レポート",
source_folder = find.package("htmlreportR"),
uncompressed_data = TRUE,
menu = "contents_list"
)
# 設定を渡してレポートを一括で作成
main_htmlreportR(opt)
Reading file kyoto_script/yasai.txt
# 出力されたファイルを確認
file.exists(file.path("kyoto_script", "kyoyasai_report.html"))
[1] TRUEtitle、source_folder、uncompressed_data、menuの各要素は、値がそのままレポートオブジェクトに渡されます。省略した場合はエラーになるため、いずれも指定してください。
<おすすめのRに関する書籍です>
以下のコマンドは、パスの解析や見出し行・列の入れ替え、特定の記号の置換など、レポートに載せるデータやテキストの形を整えるための独立した処理をまとめたコマンド群です。
パス文字列の解析:parse_pathsコマンド
ワイルドカードを含むパスの文字列を展開し、実際に存在するファイルのパスに変換します。カンマ区切りで複数のパスをまとめて渡すこともできます。
| オプション | 意味 | 初期値 |
|---|---|---|
| string | 展開するパスを含む文字列 | なし |
# 京都の直売所のCSVファイルを想定したフォルダを作成
dir.create("kyoto_report", showWarnings = FALSE)
# ファイルを作成
file.create(file.path("kyoto_report", c("uji_cha.csv", "kujo_negi.csv", "kamo_nasu.csv")))
[1] TRUE TRUE TRUE
# ワイルドカードを含むパスを解析する
dir <- "kyoto_report/*.csv"
parse_paths(dir)
[1] "kyoto_report/kamo_nasu.csv,kyoto_report/kujo_negi.csv,kyoto_report/uji_cha.csv"列名の行名への変換:col_to_rownamesコマンド
指定した列の内容をデータフレームの行名に設定し、その列自体はデータフレームから取り除きます。
| オプション | 意味 | 初期値 |
|---|---|---|
| data_frame | 操作対象のデータフレーム | なし |
| col | 新しい行名に設定しデータフレームから削除する列番号 | 1 |
# 宇治・宇治田原・和束の茶生産量データを作成
sanchi <- data.frame(
地区 = c("宇治", "宇治田原", "和束"),
生産量_kg = c(1200, 950, 800),
面積_ha = c(15, 12, 10)
)
# 地区列を行名に変換する
col_to_rownames(sanchi, col = 1)
生産量_kg 面積_ha
宇治 1200 15
宇治田原 950 12
和束 800 10宇治茶や京野菜の生産統計をHTMLレポートに載せる際、地区名を行名にしておくと、後段のコマンドで表を扱いやすくなります。
<おすすめのRに関する書籍です>
HTML形式のリスト生成:make_html_listコマンド
要素のベクトルをHTMLの順序なしリスト(ul)または順序付きリスト(ol)に変換します。list_levelsオプションで要素ごとの入れ子の深さを指定すると、階層構造を持つリストも作成できます。
| オプション | 意味 | 初期値 |
|---|---|---|
| list_content | リストを構築する要素のベクトルまたはリスト | なし |
| list_levels | 要素ごとの入れ子の深さを定めるベクトルまたはリスト | NULL |
| list_types | 要素ごとに割り当てるリストの種類(”ul”または”ol”)のベクトルまたはリスト、未指定ならdefault_typeに従う | NULL |
| default_type | list_types未指定時に使うリストの種類、”ul”(順序なし)または”ol”(順序付き) | “ul” |
# 観光エリアとスポットを、入れ子の深さとともに定義
content <- c("嵐山エリア", "渡月橋", "竹林の小径", "伏見エリア", "伏見稲荷大社")
levels <- c(0, 1, 1, 0, 1)
# 階層構造を持つHTMLリストを作成
make_html_list(list_content = content, list_levels = levels)
[1] "<li>嵐山エリア</li>\n<ul>\n<li>渡月橋</li>\n<li>竹林の小径</li>\n</ul>\n<li>伏見エリア</li>\n<ul>\n<li>伏見稲荷大社</li>\n</ul>\n"特定の記号の置換:replace_paired_markコマンド
文字列の中からパターンに一致する箇所を探し、ペアで挟まれた部分を別の記号やタグに置き換えます。Markdown風の強調記号をHTMLタグに変換する用途に向いています。
| オプション | 意味 | 初期値 |
|---|---|---|
| string | 編集対象の文字列 | なし |
| pattern | 再帰的に置換するパターン(正規表現) | なし |
| replace | 置換後の開始側・終了側の文字列を、この順で含むベクトル | なし |
# レポートの見出しに使うメモを定義
memo <- "本日の目玉は **宇治茶** です"
# アスタリスクで挟んだ部分を検出するパターンを定義
pattern <- "(\\*\\*+?)([^*]+)(\\*\\*+?)"
# ペアの記号をHTMLタグに置換
replace_paired_mark(memo, pattern, c("<strong>", "</strong>"))
[1] "本日の目玉は <strong>宇治茶</strong> です"行のヘッダーへの変換:row_to_headerコマンド
指定した行の内容をデータフレームの列名として設定し、その行はデータフレームから取り除きます。見出しが本来のヘッダーではなくデータの1行目に紛れ込んだ状態で読み込んでしまった場合に使えます。
| オプション | 意味 | 初期値 |
|---|---|---|
| data_frame | 操作対象のデータフレーム | なし |
| row | 新しい列名に設定しデータフレームから削除する行番号 | 1 |
# 見出しがデータの1行目に紛れ込んだ京野菜の出荷量データ
yasai <- data.frame(
V1 = c("品目", "九条ねぎ", "賀茂なす", "万願寺とうがらし"),
V2 = c("出荷量_kg", "480", "320", "210"),
stringsAsFactors = FALSE
)
# 1行目を列名に変換する
row_to_header(yasai, row = 1)
品目 出荷量_kg
2 九条ねぎ 480
3 賀茂なす 320
4 万願寺とうがらし 210tableメソッドにheaderオプションを指定した場合も、内部でこのコマンドが呼び出されます。
<おすすめのRに関する書籍です>
この記事が誰かの役に立ちますように。