R Shiny : radioButtonでboolean (TRUE/FALSE)を渡す方法

本日はShiny UIで YES/NO (TRUE/FASLE)の選択です。

皆さんはユーザーにYES/NOの選択をさせる場合に何を使われますか。ここでは、マイナーな2択のraidoButtonでTRUE/FALSEを引き渡す方法についてです。

checkboxInput

最初に思い浮かぶのはcheckboxInputかと思います。基本文法は以下の通りです。

checkboxInput(inputId, label, value = FALSE, width = NULL)

これを使った例は以下のような四角い箱にチェックを入れる例のやつです。

f:id:okdata:20190720101530p:plain

チョット味気ないので、shinyWidgetsパッケージ含まれるUIパーツを使うとBootstrap的にすることもできます。

switchInput

こうするとずいぶんとそれらしくYes/Noの選択ができるようになりました。

f:id:okdata:20190720102151p:plain

このどちらかで通常は満足です。

radioButtonを使った方法

統計処理のUIを作り込んでいると、複数の選択肢の中から目的のオプション値を選ぶような場合はたくさんあります。
この場合はradioButtonを使って作り込むことが多いと思います。

Shinyの標準radioButton関数

radioButtons(inputId, label, choices = NULL, selected = NULL, inline = FALSE, width = NULL, choiceNames = NULL, choiceValues = NULL)

を使う方法や、もう少しファンシーな感じではshinyWidgetsパッケージからawesomeRadio関数

awesomeRadio(inputId, label, choices, selected = NULL, inline = FALSE, status = "primary", checkbox = FALSE, width = NULL)

を使う方法が考えられます。

一つのUIの中に複数の選択肢があり、ある選択肢は3つの中から、ある選択肢は2つの中からどれかを選ぶような場合には利用するパーツも
同じようにしたくなります。そこでradioButtonで統一したいと考えた場合困るのが2つの選択肢から一つを選ぶ場合です。

例えば以下のように、選択された結果をそのまま統計処理のオプション値として与える場合です。

 wilcox.test(group1, group2, paired = FALSE, exact = TRUE)

この例ではウイルコクソン順位和検定の例ですが、正確性検定を行うときには、exact = TRUEの指定が必要です。こういった場合にUIのオプション選択画面から正確性検定を実施しますか?のような選択肢を提示して選ばせる場合、以下のような形でTRUE/FALSEを渡すとエラーになります。

radioButtons(inputId = "exactTest", label = "正確性検定を実施しますか?",
choices = c("YES" = "TRUE",
      "NO" = "FALSE"),
selected = "FALSE"),

これはradioButtonsで選択した結果のTRUEFALSEは文字列として渡されますが、wilcox.testのオプションには論理型で渡さないといけないからです。

そこで以下のような形で値を引き渡します。
exact = as.logical(as.numeric(input$exactTest))

いったん文字列を数字に直した後で(1 or 0)論理型(TRUE or FALSE)にします。

チョット考えるとわかるのですが、最初はあれ?と感じましたのでメモを残しておきます。

以下サンプルコードを掲載します。コピペすればそのまま動きます。

library(shiny)
ui <- fluidPage(
radioButtons(inputId = "exactTest", label = "正確性検定を実施しますか?",
choices = c("YES" = "1",
"NO" = "0"),
selected = "0"),
br(), hr(),
tableOutput("result.T")
)
server <- function(input, output) {
# generate data
set.seed(12345)
x0 = rnorm(100 , 0, 1) # 平均0、SD=1の正規乱数を100個作成
y0 = rnorm(100 , 0, 10)
# output table
output$result.T  = renderTable({
res = wilcox.test(x0, y0, exact = as.logical(as.numeric(input$exactTest)))
tab = data.frame(res$statistic, res$p.value)
colnames(tab) = c("統計量","p値")
rownames(tab) = "Values"
return(tab)
}, digits = 6)
}
shinyApp(ui, server)