Rで解析:Shinyの入力欄を文章の中に埋め込む「inshiny」パッケージの紹介
Shinyのテキスト入力Boxは説明文の途中に差し込むと行が分かれて読みにくいです。本パッケージは、段落や文の中に直接置ける小型のShinyウィジェットを提供するコマンドが収録されています。テキスト・数値・日付・選択メニュー・スライダー・オンオフの切り替えといった入力欄や、クリックを受け取るボタンとリンクを、周囲の文と同じ行に配置することが可能です。複数のウィジェットと文字列を1行にまとめるコンテナや、bslibを使わない画面へ読み込むための補助関数も用意されています。また、サーバー側から値やラベル、選択肢を後から差し替えることも可能です。本パッケージの利用で、説明文と一体になった入力欄を備えたShinyアプリを作成できるのではないかと考えます。
パッケージバージョンは0.1.5。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。
<おすすめのRに関する書籍です>
パッケージのインストール
下記コマンドを実行してください。
# パッケージのインストール
install.packages("inshiny")
# パッケージの読み込み
library("inshiny")コマンド例
詳細はコメント、パッケージのヘルプを確認してください。各コマンド例の末尾には、記述した画面をブラウザに表示して実行結果を確認するためのアプリ起動コマンドを添えています。
本パッケージのウィジェットは、標準のshinyと同じくidで識別し、サーバー側ではinput[[“id”]]のように値を参照します。標準のウィジェットが縦に積み上がる箱であるのに対し、本パッケージのウィジェットは行の中に収まる大きさで描画されます。各コマンドのmeaningオプションには、画面に文字が出ない場合でも内容を伝えるための説明を渡せます。
以降のコマンド例では、宇治茶の生産と出荷を管理する画面を想定し、次の共通の選択肢を使います。
# コマンド例で共通して使う選択肢をまとめる
# 宇治茶の等級(表示名 = サーバーへ渡す値)
tea_grades <- c("特上" = "premium", "上" = "grade1", "並" = "grade2")
# 抹茶の産地として選べる市町村
areas <- c("宇治市", "和束町", "宇治田原町", "南山城村")ウィジェットと文字列を1行にまとめる:inlineコマンド
インラインウィジェットと文字列やHTMLタグを受け取り、1行または1段落として横に並べます。要素の間に空白は入らないため、必要な空白は文字列の側に含めます。styleなどの名前付き引数は、行を包むdivタグの属性になります。
| オプション | 意味 | 初期値 |
|---|---|---|
| … | 横に並べるインラインウィジェット・文字列・HTMLタグ。間に空白は入らないため必要なら文字列側に空白を足す。名前付き引数は行を包むdivタグの属性になる | なし |
| class | 行に付けるクラス。既定の “mb-1″ は下側にわずかな余白を付けるBootstrap 5のクラスで、”mb-0” から “mb-5” などの間隔クラスも指定できる。複数指定は空白区切りの1文字列で渡す | “mb-1” |
# 固定幅レイアウトのページを作成
ui <- bslib::page_fixed(
# 見出しを表示
shiny::h1("宇治茶テイスティングの記録"),
# 文字列と複数のウィジェットを1行にまとめる
inline(
"本日の担当は ",
inline_text("taster", "藤井"),
" さん、試飲したのは ",
inline_number("cups", 8),
" 種類です。"
),
# 行の下側の余白を広めにしたコンテナ
inline("メモは随時更新します。", class = "mb-4")
)
# アプリを起動して実行結果を表示
shiny::shinyApp(ui = ui, server = function(input, output, session) {})
文中に文字入力欄を置く:inline_textコマンド
文章の中に1行分の文字入力欄を置きます。placeholderで空欄時の案内を、max_widthで入力欄の最大幅を指定できます。入力がその幅を超えると、欄の中が横スクロールになります。
| オプション | 意味 | 初期値 |
|---|---|---|
| id | 値を取り出すときに使う入力スロットの名前 | なし |
| value | 初期のテキスト内容(文字列) | “” |
| placeholder | 空のときに枠内へ表示する案内の文字列またはHTML要素 | “Enter text” |
| meaning | スクリーンリーダーなどの支援技術の利用者向けの説明ラベル | NULL |
| max_width | 入力欄の最大幅をCSSの長さで指定する。これを超えると横スクロールになる。NULLで制限なし | “10em” |
# 固定幅レイアウトのページを作成
ui <- bslib::page_fixed(
# 見出しを表示
shiny::h1("茶園の記録"),
# 文中に文字入力欄を埋め込む
inline(
"収穫を担当した圃場は ",
# 空欄時の案内と最大幅、支援技術向けの説明を指定
inline_text("field", value = "", placeholder = "圃場名を入力",
meaning = "収穫した圃場の名前", max_width = "14em"),
" です。"
)
)
# アプリを起動して実行結果を表示
shiny::shinyApp(ui = ui, server = function(input, output, session) {})
文中に数値入力欄を置く:inline_numberコマンド
文章の中に数値入力欄を置きます。minとmaxで範囲を、stepで上下キーや矢印による増減の刻み幅を指定します。arrowsをFALSEにすると、欄の横のクリックできる矢印を隠せます。
| オプション | 意味 | 初期値 |
|---|---|---|
| id | 値を取り出すときに使う入力スロットの名前 | なし |
| value | 初期の数値 | なし |
| min | 最小値。NULLで制限なし | NULL |
| max | 最大値。NULLで制限なし | NULL |
| step | 上下キーや矢印で増減させるときの刻み幅。Page Up/Down は10刻み、Home/End は最小値・最大値へ移動する。既定は1 | NULL |
| default | 入力が無効または空のときに使う既定値 | value |
| placeholder | 空のときに枠内へ表示する案内の文字列またはHTML要素 | “Enter number” |
| meaning | スクリーンリーダーなどの支援技術の利用者向けの説明ラベル | NULL |
| max_width | 入力欄の最大幅をCSSの長さで指定する。NULLで制限なし | “10em” |
| arrows | 数値を上下に調整するクリック可能な矢印を表示するかどうか | TRUE |
# 固定幅レイアウトのページを作成
ui <- bslib::page_fixed(
# 見出しを表示
shiny::h1("焙煎の設定"),
# 文中に数値入力欄を埋め込む
inline(
"焙煎温度は ",
# 下限・上限・刻み幅を指定し、矢印は非表示にする
inline_number("temp", value = 130, min = 90, max = 200, step = 5,
arrows = FALSE),
" 度で行います。"
)
)
# アプリを起動して実行結果を表示
shiny::shinyApp(ui = ui, server = function(input, output, session) {})
<おすすめのRに関する書籍です>
文中に選択メニューを置く:inline_selectコマンド
文章の中にドロップダウンの選択メニューを置きます。choicesには名前なしベクトルのほか、表示名と値を分けた名前付きベクトルや、見出しでまとめた名前付きリストを渡せます。multipleをTRUEにすると複数選択になります。
| オプション | 意味 | 初期値 |
|---|---|---|
| id | 値を取り出すときに使う入力スロットの名前 | なし |
| choices | 選択肢の値のベクトルまたはリスト。名前なしベクトル、表示名と値を分けた名前付きベクトル、見出しでまとめた名前付きリストのいずれかを渡す | なし |
| selected | 初期選択の値。NULLならchoicesの先頭 | NULL |
| multiple | 複数選択を許すかどうか。バージョン0.1.0時点では、TRUEのときの見た目と挙動がFALSEのときと一部異なる | FALSE |
| meaning | スクリーンリーダーなどの支援技術の利用者向けの説明ラベル | NULL |
| max_width | 入力欄の最大幅をCSSの長さで指定する。NULLで制限なし | “10em” |
# 固定幅レイアウトのページを作成
ui <- bslib::page_fixed(
# 見出しを表示
shiny::h1("出荷の指定"),
# 文中に選択メニューを埋め込む
inline(
"等級 ",
# 表示名と値が異なる名前付きベクトルを選択肢にする
inline_select("grade", choices = tea_grades, selected = "grade1"),
" を ",
# 複数選択を許可し、産地を選ばせる
inline_select("area", choices = areas, multiple = TRUE),
" から出荷します。"
)
)
# アプリを起動して実行結果を表示
shiny::shinyApp(ui = ui, server = function(input, output, session) {})
文中にスライダーを置く:inline_sliderコマンド
文章の中にスライダーを置きます。数値入力欄と目盛りが組み合わさった形で、value・min・maxはいずれも指定が必須です。stepでminからmaxの間を飛ぶ刻み幅を決めます。
| オプション | 意味 | 初期値 |
|---|---|---|
| id | 値を取り出すときに使う入力スロットの名前 | なし |
| value | 初期の数値 | なし |
| min | 最小値。指定は必須 | なし |
| max | 最大値。指定は必須 | なし |
| step | minからmaxの間をスライダーが飛ぶ刻み幅 | NULL |
| default | 入力が無効または空のときに使う既定値 | value |
| placeholder | 空のときに枠内へ表示する案内の文字列またはHTML要素 | “Enter number” |
| meaning | スクリーンリーダーなどの支援技術の利用者向けの説明ラベル | NULL |
| max_width | 入力欄の最大幅をCSSの長さで指定する。NULLで制限なし | “10em” |
# 固定幅レイアウトのページを作成
ui <- bslib::page_fixed(
# 見出しを表示
shiny::h1("ブレンドの調整"),
# 文中にスライダーを埋め込む
inline(
"かぶせ茶の配合比は ",
# 値・最小・最大は必須。刻み幅を5に設定
inline_slider("ratio", value = 40, min = 0, max = 100, step = 5),
" %です。"
)
)
# アプリを起動して実行結果を表示
shiny::shinyApp(ui = ui, server = function(input, output, session) {})
文中にオン・オフの切り替えを置く:inline_switchコマンド
文章の中にオンとオフを切り替えるスイッチを置きます。valueがFALSEでオフ、TRUEでオンの状態から始まります。onとoffには、スイッチの右側に出すラベルを文字列やHTML要素で指定でき、NULLでラベルなしになります。
| オプション | 意味 | 初期値 |
|---|---|---|
| id | 値を取り出すときに使う入力スロットの名前 | なし |
| value | スイッチの初期状態。FALSEでオフ、TRUEでオン | なし |
| on | スイッチがオンのとき右側に表示するラベル。文字列やHTML要素を指定でき、NULLでラベルなし | “On” |
| off | スイッチがオフのとき右側に表示するラベル。文字列やHTML要素を指定でき、NULLでラベルなし | “Off” |
| meaning | スクリーンリーダーなどの支援技術の利用者向けの説明ラベル | NULL |
# 固定幅レイアウトのページを作成
ui <- bslib::page_fixed(
# 見出しを表示
shiny::h1("加工の指定"),
# 文中にスイッチを2つ埋め込む
inline(
"石臼挽きは ",
# オン・オフ時のラベルを日本語にする
inline_switch("mill", value = TRUE, on = "する", off = "しない"),
" 、火入れは ",
inline_switch("roast", value = FALSE, on = "する", off = "しない"),
" 設定です。"
)
)
# アプリを起動して実行結果を表示
shiny::shinyApp(ui = ui, server = function(input, output, session) {})
文中にカレンダー付き日付入力を置く:inline_dateコマンド
文章の中に、クリックするとカレンダーが開く日付入力欄を置きます。value・min・max・datesdisabledは表示書式に関わらず “yyyy-mm-dd” 形式かDateオブジェクトで渡します。formatは画面表示だけを変え、weekstartやdaysofweekdisabledで週の始まりや選択不可の曜日を調整できます。
| オプション | 意味 | 初期値 |
|---|---|---|
| id | 値を取り出すときに使う入力スロットの名前 | なし |
| value | 初期選択の日付。Dateオブジェクト、”yyyy-mm-dd” 形式の文字列、またはNULLで利用者のタイムゾーンの当日 | NULL |
| min | 選択できる最小の日付。Dateオブジェクト、”yyyy-mm-dd” 形式の文字列、またはNULLで制限なし | NULL |
| max | 選択できる最大の日付。Dateオブジェクト、”yyyy-mm-dd” 形式の文字列、またはNULLで制限なし | NULL |
| placeholder | 空のときに枠内へ表示する案内の文字列またはHTML要素 | “Enter date” |
| meaning | スクリーンリーダーなどの支援技術の利用者向けの説明ラベル | NULL |
| max_width | 入力欄の最大幅をCSSの長さで指定する。NULLで制限なし | “10em” |
| format | ブラウザに表示する日付の書式。表示専用で、value・min・max・datesdisabledは “yyyy-mm-dd” 形式かDateオブジェクトのままにする | “yyyy-mm-dd” |
| startview | 枠を最初にクリックしたときの表示。”month”、”year”、”decade” を指定できる | “month” |
| weekstart | 週の始まりの曜日。0(日曜)から6(土曜)の整数 | 0 |
| language | 月名と曜日名に使う言語。既定は “en”(英語) | “en” |
| autoclose | 日付を選んだらカレンダーを閉じるかどうか | TRUE |
| datesdisabled | 選択不可にする日付(文字列またはDateのベクトル)。文字列は “yyyy-mm-dd” 形式 | NULL |
| daysofweekdisabled | 選択不可にする曜日。0が日曜、6が土曜の整数ベクトル | NULL |
# 固定幅レイアウトのページを作成
ui <- bslib::page_fixed(
# 見出しを表示
shiny::h1("収穫日の指定"),
# 文中に日付入力欄を埋め込む
inline(
"一番茶の収穫予定日は ",
# 表示書式・週の開始曜日・選択不可の曜日を指定
inline_date("harvest", value = "2026-05-08", min = "2026-04-20",
max = "2026-06-10", format = "yyyy/mm/dd", weekstart = 1,
daysofweekdisabled = c(0, 6)),
" です。"
)
)
# アプリを起動して実行結果を表示
shiny::shinyApp(ui = ui, server = function(input, output, session) {})
文中に操作ボタンを置く:inline_buttonコマンド
文章の中に、shinyのactionButtonと同じように押下回数を受け取れるボタンを置きます。iconにshiny::icon()を渡すとラベルの左にアイコンが付き、accentにBootstrapのアクセント名を渡すとボタンの色が変わります。
| オプション | 意味 | 初期値 |
|---|---|---|
| id | 値を取り出すときに使う入力スロットの名前 | なし |
| label | ボタン内に表示する文字列またはHTML。NULLで文字なし(その場合はアイコンを付ける) | なし |
| icon | ボタンの左側に表示する任意の shiny::icon() | NULL |
| meaning | スクリーンリーダーなどの支援技術の利用者向けの説明ラベル | label |
| accent | ボタンのクラスに使うBootstrapのアクセント(”primary”、”danger” など)。NULLで既定の “btn-default”。複数指定すると各値が “btn-” に付いて追加される | NULL |
# 固定幅レイアウトのページを作成
ui <- bslib::page_fixed(
# 見出しを表示
shiny::h1("記録の保存"),
# 文中に操作ボタンを埋め込む
inline(
"入力が終わったら ",
# アイコン付きで、アクセント色を primary にする
inline_button("save", label = "保存", icon = shiny::icon("floppy-disk"),
accent = "primary"),
" を押してください。"
)
)
# アプリを起動して実行結果を表示
shiny::shinyApp(ui = ui, server = function(input, output, session) {})
文中にクリックできるリンクを置く:inline_linkコマンド
文章の中に、押下回数をサーバーで受け取れるリンクを置きます。使い方はinline_buttonと同じで、見た目がボタンではなくテキストリンクになります。accentにはリンク用のBootstrapのアクセント名を渡します。
| オプション | 意味 | 初期値 |
|---|---|---|
| id | 値を取り出すときに使う入力スロットの名前 | なし |
| label | リンク内に表示する文字列またはHTML。NULLで文字なし(その場合はアイコンを付ける) | なし |
| icon | リンクの左側に表示する任意の shiny::icon() | NULL |
| meaning | スクリーンリーダーなどの支援技術の利用者向けの説明ラベル | label |
| accent | リンクのクラスに使うBootstrapのアクセント(”primary”、”danger” など)。NULLで特別な装飾なし。複数指定すると各値が “link-” に付いて追加される | NULL |
# 固定幅レイアウトのページを作成
ui <- bslib::page_fixed(
# 見出しを表示
shiny::h1("参考資料"),
# 文中にクリックできるリンクを埋め込む
inline(
"等級の基準は ",
# クリックをサーバーで受け取れるリンク。アクセントで色を付ける
inline_link("spec", label = "出荷規格の一覧", icon = shiny::icon("book"),
accent = "primary"),
" で確認できます。"
)
)
# アプリを起動して実行結果を表示
shiny::shinyApp(ui = ui, server = function(input, output, session) {})
bslib以外のUIで読み込む:use_inshinyコマンド
bslibのページ関数(page_fixedなど)を使うと本パッケージのスクリプトと様式は自動で読み込まれますが、shiny::fluidPageなど他のUIを使う場合は、UIのどこかにこの関数の戻り値を置いて読み込みます。オプションはありません。
# bslibのページ関数を使わない場合の書き方
ui <- shiny::fluidPage(
# inshinyのスクリプトと様式を読み込む
use_inshiny(),
# 見出しを表示
shiny::h1("宇治茶テイスティングの記録"),
# 文中に数値入力欄を埋め込む
inline(
"試飲したのは ",
inline_number("cups", 8),
" 種類です。"
)
)
# アプリを起動して実行結果を表示
shiny::shinyApp(ui = ui, server = function(input, output, session) {})
サーバー側からウィジェットを更新する:update_inlineコマンド
サーバー側から、UIに置いたインラインウィジェットの値・ラベル・選択肢などを後から差し替えます。idで対象を指定し、更新したい項目だけを名前付きで渡します。渡せる項目はウィジェットの種類ごとに決まっており、表の意味欄のかっこ内が対応する種類です。次のコードは、これまでのコマンド例のUIに対応するサーバー処理です。
| オプション | 意味 | 初期値 |
|---|---|---|
| id | 変更するインラインウィジェットのID | なし |
| session | 現在のShinyセッション。ほぼ常に既定のままでよい | shiny::getDefaultReactiveDomain() |
| value | (date, number, select, slider, switch, text)ウィジェットの現在値 | なし |
| placeholder | (date, number, slider, text)枠が空のときに表示する案内 | なし |
| meaning | (すべてのウィジェット)支援技術の利用者向けの説明ラベル | なし |
| label | (button, link)ボタンやリンクに表示するラベル | なし |
| icon | (button, link)ボタンやリンクに表示するアイコン | なし |
| accent | (button, link)ボタンやリンクに適用するBootstrapのアクセント | なし |
| min | (date, number, slider)許容する最小値 | なし |
| max | (date, number, slider)許容する最大値 | なし |
| step | (number, slider)値を増減させる刻み幅 | なし |
| default | (number, slider)入力が空または無効なときに使う既定値 | なし |
| on | (switch)スイッチがオンのときのラベル | なし |
| off | (switch)スイッチがオフのときのラベル | なし |
| datesdisabled | (date)選択不可にする日付 | なし |
| daysofweekdisabled | (date)選択不可にする曜日 | なし |
| choices | (select)選択肢 | なし |
| selected | (select)現在の選択 | なし |
# 更新の対象となるウィジェットを1画面にまとめたページを作成
ui <- bslib::page_fixed(
# 見出しを表示
shiny::h1("出荷内容の更新"),
# 等級・産地・配合比・保存ボタンを1行に並べる
inline(
"等級 ",
inline_select("grade", choices = tea_grades),
" 、産地 ",
inline_select("area", choices = areas),
" 、かぶせ茶の配合比 ",
inline_slider("ratio", value = 40, min = 0, max = 100, step = 5),
" %で ",
inline_button("save", label = "保存"),
" します。"
)
)
# これまでのコマンド例のUIに対応するサーバー処理
server <- function(input, output, session) {
# 等級が特上のときだけ、産地の選択肢と選択値を差し替える
shiny::observeEvent(input$grade, {
if (input$grade == "premium") {
update_inline("area", choices = c("和束町", "南山城村"),
selected = "和束町")
}
})
# 保存ボタンが押されたら、ラベルとアイコンを押下後の表示へ変える
shiny::observeEvent(input$save, {
update_inline("save", label = "保存しました",
icon = shiny::icon("check"), accent = "success")
})
# スライダーの範囲と刻み幅を後から狭める
update_inline("ratio", min = 20, max = 60, step = 10, default = 40)
}
# アプリを起動して実行結果を表示
shiny::shinyApp(ui = ui, server = server)
<おすすめのRに関する書籍です>
この記事が誰かの役に立ちますように。