本文へスキップ
からだにいいもの

Rのトピックスを中心に『まだ、まだ、知らない、役に立つ情報?』を発信します。

Rで解析:Shinyの入力欄を文章の中に埋め込む「inshiny」パッケージの紹介

Shinyのテキスト入力Boxは説明文の途中に差し込むと行が分かれて読みにくいです。本パッケージは、段落や文の中に直接置ける小型のShinyウィジェットを提供するコマンドが収録されています。テキスト・数値・日付・選択メニュー・スライダー・オンオフの切り替えといった入力欄や、クリックを受け取るボタンとリンクを、周囲の文と同じ行に配置することが可能です。複数のウィジェットと文字列を1行にまとめるコンテナや、bslibを使わない画面へ読み込むための補助関数も用意されています。また、サーバー側から値やラベル、選択肢を後から差し替えることも可能です。本パッケージの利用で、説明文と一体になった入力欄を備えたShinyアプリを作成できるのではないかと考えます。

パッケージバージョンは0.1.5。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。

パッケージのインストール

下記コマンドを実行してください。

# パッケージのインストール
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 は最小値・最大値へ移動する。既定は1NULL
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) {})

文中に選択メニューを置く: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最大値。指定は必須なし
stepminから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)


この記事が誰かの役に立ちますように。

スポンサーリンク
価格および配送状況は変更される場合があります。購入時は商品ページをご確認ください。
当サイトに表示されている商品情報はAmazonから提供されたものであり、更新または削除される場合があります。
karada-goodはAmazonアソシエイトとして、適格販売により収入を得ています。