R Shiny を使ってWebアプリを作って動くまでやってみる(10) サブメニューの作成

本シリーズでは、「心理学の尺度開発」に特化した、GUIベースの統計処理ソフトを作り上げることを目指しています。

今回は「前処理」に関連する部分を作っていきます。前処理といっても、基本統計量の計算から始まって、相関、シーリング、正規性の検定などいくつかのサブメニューが必要になります。基本的なコンセプトとして手順に沿っていけば処理が完成するフローを念頭に置いていますので、UIもフローを意識したものとして作っていきます。

今回つくるフロー画面のイメージ

今回の部分を作り込むと以下のような画面ができます。メニューが2段階になっていて、

[Data Upload] –> [Pre-Treatments] –> [Internal Consistency] –> […]の流れで進むメニューと、その下には[Pre-Treatments]のサブメニューとして[Check basic Stats] –> [Univariate Stat Check] –> [Correlations]のように進むメニューの2段構成です。具体的なメニューの内容に関しては今後内容を検討しながら開発を進めていきますが、イメージとしてこのような形でステップを踏んで進めていくことができるようになっています。

今回作ったプログラム部分

[global.R]のプログラムの8行目の分割したUIのプログラムの名前を前回までとは変更しています。

#global.R
library(shiny)
library(shinydashboard)
library(DT)
library(shinyWidgets)

source("ui_01_001_dataUpload.R", local = TRUE)
source("ui_02_000_preTreatments.R", local = TRUE)
source("ui_03_000_internalConsistency.R", local = TRUE)
#ui.R
shinyUI(fluidPage(

    dashboardPage(
        dashboardHeader(title = "Psycho Scale Developer", disable = FALSE, titleWidth = "300px"),
        dashboardSidebar(
            disable = TRUE
        ),
        dashboardBody(
            
            
            #######################
            # header
            #######################
            tags$head(tags$style(HTML('
            
                                  .well {
                                  background-color: initial;
                                  border: initial;
                                  }
                                  
                                  .navbar {
                                  margin-bottom: 5px;
                                  }
                                  
                                 .container-fluid {padding-right: 10px; padding-left: 10px}

                                  '))),
            
            navbarPage("Main Menus", id="mainTabs", selected = "dataUpload", 
                       # menu1 Data Upload
                       ui_01_001_dataUpload, 
                       
                       # menu2 Basic Stats
                       ui_02_000_pretreatments,
                       
                       # menu3 Internal Consistency
                       ui_03_000_internalConsistency
                       
            ) # end of navBarPage

        ) # end of dashboardBody
    )
))

#ui_02_000_preTreatments.R
ui_02_000_pretreatments = 
  tabPanel(title = "Pre-Treatments", value="preTreatments", icon = icon("line-chart"),
           
           ###########################
           # sub menus
           ###########################
           
           # sub-menu in tabPanel3 Pre-treatment
           tabsetPanel(type="tabs", id="preTreatPanel",
                       
                       ###############################
                       # sub-tab 1 : basic statistics
                       ###############################
                       
                       tabPanel(value= "basicStats", tagList(img(src="./barChart.png",style="margin-left: 5px; margin-bottom:4px; margin-top:0px; width: 50px; height: 50px;"),
                                                             div(style="font-size:10px; color: #000000; text-align:center;",
                                                                 HTML(' '),"Check",HTML(' '),
                                                                 br(),
                                                                 HTML(' '),"Basic stats",HTML(' '))),
                               
                               ####################
                               # sidebar panel
                               ####################
                               
                               sidebarPanel(width=4, style ="margin-left: -35px; ",
                                            fluidRow(style="border: 1px solid #d0cece; padding-top: 30px; padding-bottom: 5px; margin-bottom: 10px;",
                                                     p("Basic Statistics", style="font-size: 20px; margin-top: -20px; padding-left: 20px;")
                                            ),
                                            
                                            fluidRow(width=12, style = "padding-bottom: 10px; border: 1px solid #d0cdcd;",
                                                     
                                                     column(width=6,
                                                            p(img(src="./candidate-list.png", width="25px", height="25px;"),
                                                              "Candidate Variables", style="font-size:12px; margin-top: 20px; margin-bottom: 3px"), 
                                                            uiOutput("elementsCandiate", 
                                                                     style = "min-height:40vh;background-color:white;line-height: 1.2em; overflow-y:scroll;")
                                                            
                                                     ),
                                                     column(width=6,
                                                            p(img(src="./stethoscope.png", width="25px", height="25px;"),
                                                              "Selected Variables", style="font-size:12px; margin-top: 20px; margin-bottom: 3px"), 
                                                            uiOutput("elementsSelected", 
                                                                     style = "min-height:40vh;background-color:white;line-height: 1.2em; overflow-y:scroll;")
                                                     )
                                            )
                                            
                               ), # end of sidebar panel

                               ###############
                               # main panel
                               ###############
                               
                               mainPanel(width=8,
                                         br(),
                                         fluidRow(width=12, style = "margin-left: 0px; margin-right: -60px; margin-bottom: 30px;",
                                                  div(uiOutput("basicStatsPlot"), style="")
                                         )
                                         
                               ) # end of mainPanel
                       
                       ),
                       
                       
                       ##################################
                       # sub-tab2 Univariate
                       ##################################
                       
                       tabPanel(value="tabImg2", div(class="tabimg", img(src="./forward.png", width="40px", height="50px"), style="margin-top: 15px;")
                       ),
                       
                       tabPanel(value="uniStat", tagList(img(src="./research.png",
                                                             style="margin-left: 5px; margin-bottom:4px; margin-top:0px; width: 50px; height: 50px;"),
                                                         div(style="font-size:10px; color: #000000; text-align:center;",
                                                             HTML(' '),"Univariate",HTML(' '),
                                                             br(),
                                                             HTML(' '),"Stat Check",HTML(' '))),

                                ####################
                                # sidebar panel
                                ####################
                                
                                sidebarPanel(width=4, style ="margin-left: -35px; background-color:#f1f1f1; border-color:#f1f1f1;"
                                ), # end of sidebarPanel
                                
                                ###############
                                # main panel
                                ###############
                                
                                mainPanel(width=8, style="margin-left: -20px; margin-right:-20px;"
                                )
                                
                       ),
                       
                       tabPanel(value="tabImg2", div(class="tabimg", img(src="./forward.png", width="40px", height="50px"), style="margin-top: 15px;")
                       ),
                       

                       #############################
                       # sub-tab 3 Correlation Check
                       #############################
                       
                       tabPanel(value="tabCorr", tagList(img(src="./diversify.png",
                                                             style="margin-bottom:4px; margin-top:0px; width: 50px; height: 50px;"),
                                                         div(style="font-size:10px; color: #000000; text-align:center;", "Correlations",br(),br())),
                                
                                ####################
                                # sidebar panel
                                ####################
                                
                                sidebarPanel(width=4, style ="margin-left: -35px; background-color:#f1f1f1; border-color:#f1f1f1;"
                                ),
                                
                                ###############
                                # main panel
                                ###############
                                
                                mainPanel(width=8, style="margin-left: -20px; margin-right:-20px;"
                                )
                                
                       )
                       
           ) # ene of tabSetPane --- preTreatPanel
           
  )  # end of tabPanel --- pretreatments

プログラムの補足説明

ui.Rの15−28行目では画面のスタイル(色や幅などの見かけ)を調整しています。ここをコメントアウトしてみるとどのように変わるか確認してみてください。

ui_02_000_preTreatments.Rの10ー123行目でサブメニューを作っています。もともとこのUI部分は一つのタブパネルの中を記述しているのですが、更に、10行目に`tabsetPanel`があります。こういった形で入れ子でタブセットを作ることが可能です。

16−62行目がサブメニューの最初のタブ[Basic Stats]の部分です。内部は、サイドバーパネルとメインパネルからできているがわかると思います。

サイドバーパネルは大きく分けて、[Candidate Variables]と[Selected Variables]の二つの要素があります。`draglaSelectR`を使って変数の選択を行うことを念頭に、変数の一覧が並ぶ部分[Candidate Variables]から変数をドラッグして[Selected Variables]にドロップするとその変数に関する結果が出力されることを想定しています。`draglaSelectR`を使ったドラッグ&ドロップについては以下のブログをご覧ください。

サブメニュー2,3を含めて枠しか作ってありませんが、今後作り込んでいく予定です。

アイコンについて

本プログラムで使っている画像はフリー素材を利用しています。[free icon]のキーワード検索するといくつか無償利用可能なアイコンを提供しているサイトがありますので適宜使ってください。

`Shiny`では、プログラムが入っているホルダーと同じ階層に`www`の名前でフォルダーをおき、その中に画像などをいれるルールですのでご留意ください。

まとめ

今回はメニューを入れ子構造にしてメニュー画面を作り込みました。こうすることで、メニューを順番に処理することで必要な前処理をすべて実施できることが期待されます。

さらに作り込むとすると、前処理の順番や要・不要などデータの流れをフローチャート形式で矢印をつなぐだけで処理が進んでいくようなUIにすれば更にfancyになりますが、今回はそこまで作り込む予定はありません。不要処理を飛ばすことができる形で作る予定です。

次回は、基本統計量の計算をいくつか実装してみる予定です。