shiny library

….

2024-12-17

Introduction

In this exercise, we will delve into the capabilities of the shiny package, build a simple Shiny application, and enhance its features with customized input and output components. The shiny package is an essential tool in R that allows users to create dynamic and interactive web-based applications seamlessly within the R environment.

Step 1: Package Discovery and Installation

Installing and Loading the Package

# Install shiny (if not already installed)
if (!requireNamespace("shiny", quietly = TRUE)) {
  install.packages("shiny")
}
library(shiny)
## Warning: package 'shiny' was built under R version 4.3.3

Exploring the Package Documentation

# Display package documentation
?shiny
## starting httpd help server ... done

Step 2: Analyzing the Package Structure

Listing Functions and Datasets

# List all exported functions
ls("package:shiny")
##   [1] "a"                        "absolutePanel"           
##   [3] "actionButton"             "actionLink"              
##   [5] "addResourcePath"          "animationOptions"        
##   [7] "appendTab"                "as.shiny.appobj"         
##   [9] "basicPage"                "bindCache"               
##  [11] "bindEvent"                "bookmarkButton"          
##  [13] "bootstrapLib"             "bootstrapPage"           
##  [15] "br"                       "browserViewer"           
##  [17] "brushedPoints"            "brushOpts"               
##  [19] "busyIndicatorOptions"     "callModule"              
##  [21] "captureStackTraces"       "checkboxGroupInput"      
##  [23] "checkboxInput"            "clickOpts"               
##  [25] "code"                     "column"                  
##  [27] "conditionalPanel"         "conditionStackTrace"     
##  [29] "conditionStackTrace<-"    "createRenderFunction"    
##  [31] "createWebDependency"      "dataTableOutput"         
##  [33] "dateInput"                "dateRangeInput"          
##  [35] "dblclickOpts"             "debounce"                
##  [37] "devmode"                  "dialogViewer"            
##  [39] "diskCache"                "div"                     
##  [41] "downloadButton"           "downloadHandler"         
##  [43] "downloadLink"             "em"                      
##  [45] "enableBookmarking"        "eventReactive"           
##  [47] "exportTestValues"         "exprToFunction"          
##  [49] "ExtendedTask"             "fileInput"               
##  [51] "fillCol"                  "fillPage"                
##  [53] "fillRow"                  "fixedPage"               
##  [55] "fixedPanel"               "fixedRow"                
##  [57] "flowLayout"               "fluidPage"               
##  [59] "fluidRow"                 "freezeReactiveVal"       
##  [61] "freezeReactiveValue"      "get_devmode_option"      
##  [63] "getCurrentOutputInfo"     "getCurrentTheme"         
##  [65] "getDefaultReactiveDomain" "getQueryString"          
##  [67] "getShinyOption"           "getUrlHash"              
##  [69] "h1"                       "h2"                      
##  [71] "h3"                       "h4"                      
##  [73] "h5"                       "h6"                      
##  [75] "headerPanel"              "helpText"                
##  [77] "hideTab"                  "hoverOpts"               
##  [79] "hr"                       "HTML"                    
##  [81] "htmlOutput"               "htmlTemplate"            
##  [83] "httpResponse"             "icon"                    
##  [85] "imageOutput"              "img"                     
##  [87] "in_devmode"               "includeCSS"              
##  [89] "includeHTML"              "includeMarkdown"         
##  [91] "includeScript"            "includeText"             
##  [93] "incProgress"              "inputPanel"              
##  [95] "insertTab"                "insertUI"                
##  [97] "installExprFunction"      "invalidateLater"         
##  [99] "is.key_missing"           "is.reactive"             
## [101] "is.reactivevalues"        "is.shiny.appobj"         
## [103] "is.singleton"             "isolate"                 
## [105] "isRunning"                "isTruthy"                
## [107] "key_missing"              "loadSupport"             
## [109] "mainPanel"                "makeReactiveBinding"     
## [111] "markdown"                 "markRenderFunction"      
## [113] "maskReactiveContext"      "memoryCache"             
## [115] "MockShinySession"         "modalButton"             
## [117] "modalDialog"              "moduleServer"            
## [119] "navbarMenu"               "navbarPage"              
## [121] "navlistPanel"             "nearPoints"              
## [123] "need"                     "NS"                      
## [125] "ns.sep"                   "numericInput"            
## [127] "observe"                  "observeEvent"            
## [129] "onBookmark"               "onBookmarked"            
## [131] "onFlush"                  "onFlushed"               
## [133] "onReactiveDomainEnded"    "onRestore"               
## [135] "onRestored"               "onSessionEnded"          
## [137] "onStop"                   "onUnhandledError"        
## [139] "outputOptions"            "p"                       
## [141] "pageWithSidebar"          "paneViewer"              
## [143] "parseQueryString"         "passwordInput"           
## [145] "plotOutput"               "plotPNG"                 
## [147] "pre"                      "prependTab"              
## [149] "printError"               "printStackTrace"         
## [151] "Progress"                 "quoToFunction"           
## [153] "radioButtons"             "reactive"                
## [155] "reactiveConsole"          "reactiveFileReader"      
## [157] "reactivePoll"             "reactiveTimer"           
## [159] "reactiveVal"              "reactiveValues"          
## [161] "reactiveValuesToList"     "reactlog"                
## [163] "reactlogAddMark"          "reactlogReset"           
## [165] "reactlogShow"             "register_devmode_option" 
## [167] "registerInputHandler"     "registerThemeDependency" 
## [169] "removeInputHandler"       "removeModal"             
## [171] "removeNotification"       "removeResourcePath"      
## [173] "removeTab"                "removeUI"                
## [175] "renderCachedPlot"         "renderDataTable"         
## [177] "renderImage"              "renderPlot"              
## [179] "renderPrint"              "renderTable"             
## [181] "renderText"               "renderUI"                
## [183] "repeatable"               "req"                     
## [185] "resourcePaths"            "restoreInput"            
## [187] "runApp"                   "runExample"              
## [189] "runGadget"                "runGist"                 
## [191] "runGitHub"                "runTests"                
## [193] "runUrl"                   "safeError"               
## [195] "selectInput"              "selectizeInput"          
## [197] "serverInfo"               "setBookmarkExclude"      
## [199] "setProgress"              "setSerializer"           
## [201] "shinyApp"                 "shinyAppDir"             
## [203] "shinyAppFile"             "shinyAppTemplate"        
## [205] "shinyOptions"             "shinyServer"             
## [207] "shinyUI"                  "showBookmarkUrlModal"    
## [209] "showModal"                "showNotification"        
## [211] "showTab"                  "sidebarLayout"           
## [213] "sidebarPanel"             "singleton"               
## [215] "sizeGrowthRatio"          "sliderInput"             
## [217] "snapshotExclude"          "snapshotPreprocessInput" 
## [219] "snapshotPreprocessOutput" "span"                    
## [221] "splitLayout"              "stopApp"                 
## [223] "strong"                   "submitButton"            
## [225] "suppressDependencies"     "tableOutput"             
## [227] "tabPanel"                 "tabPanelBody"            
## [229] "tabsetPanel"              "tag"                     
## [231] "tagAppendAttributes"      "tagAppendChild"          
## [233] "tagAppendChildren"        "tagGetAttribute"         
## [235] "tagHasAttribute"          "tagList"                 
## [237] "tags"                     "tagSetChildren"          
## [239] "testServer"               "textAreaInput"           
## [241] "textInput"                "textOutput"              
## [243] "throttle"                 "titlePanel"              
## [245] "uiOutput"                 "updateActionButton"      
## [247] "updateActionLink"         "updateCheckboxGroupInput"
## [249] "updateCheckboxInput"      "updateDateInput"         
## [251] "updateDateRangeInput"     "updateNavbarPage"        
## [253] "updateNavlistPanel"       "updateNumericInput"      
## [255] "updateQueryString"        "updateRadioButtons"      
## [257] "updateSelectInput"        "updateSelectizeInput"    
## [259] "updateSliderInput"        "updateTabsetPanel"       
## [261] "updateTextAreaInput"      "updateTextInput"         
## [263] "updateVarSelectInput"     "updateVarSelectizeInput" 
## [265] "urlModal"                 "useBusyIndicators"       
## [267] "validate"                 "validateCssUnit"         
## [269] "varSelectInput"           "varSelectizeInput"       
## [271] "verbatimTextOutput"       "verticalLayout"          
## [273] "wellPanel"                "with_devmode"            
## [275] "withLogErrors"            "withMathJax"             
## [277] "withProgress"             "withReactiveDomain"      
## [279] "withTags"
# List datasets provided by ggplot2
data(package = "shiny")
## no data sets found

Step 3: Solving a Practical Problem

Creating a simple Shiny app

we will create a simple Shiny app that lets users choose a dataset and plot it..

#library(shiny)

# Define UI
ui <- fluidPage(
  titlePanel("Simple Shiny App"),
  sidebarLayout(
    sidebarPanel(
      selectInput("dataset", "Choose a dataset:", 
                  choices = c("mtcars", "iris"))
    ),
    mainPanel(
      tableOutput("table")
    )
  )
)

# Define server logic
server <- function(input, output) {
  output$table <- renderTable({
    dataset <- get(input$dataset)
    head(dataset)  # Show the first few rows of the selected dataset
  })
}

# Run the application
shinyApp(ui = ui, server = server)
Shiny applications not supported in static R Markdown documents

Step 4: Extending the Package

Creating a Custom Function

We can add custom features to make the app more interactive, such as adding sliders, filters, or reactive expressions. Let’s enhance the app by allowing users to filter data points based on a slider.s.

#install.packages("ggplot22")
library(ggplot2)
# Update UI with a slider for filtering
ui <- fluidPage(
  titlePanel("Dataset Explorer with Filter"),
  sidebarLayout(
    sidebarPanel(
      selectInput("dataset", "Choose a dataset:", 
                  choices = c("mtcars", "iris")),
      selectInput("xvar", "X-axis variable:", choices = NULL),
      selectInput("yvar", "Y-axis variable:", choices = NULL),
      sliderInput("obs", "Number of observations to display:", 
                  min = 1, max = 100, value = 50)
    ),
    mainPanel(
      plotOutput("plot")
    )
  )
)

# Modify server logic for filtered data
server <- function(input, output, session) {
  
  observeEvent(input$dataset, {
    dataset <- get(input$dataset)
    updateSelectInput(session, "xvar", choices = names(dataset))
    updateSelectInput(session, "yvar", choices = names(dataset))
  })
  
  output$plot <- renderPlot({
    dataset <- get(input$dataset)
    dataset <- dataset[1:input$obs, ]
    ggplot(dataset, aes_string(x = input$xvar, y = input$yvar)) +
      geom_point() +
      theme_minimal()
  })
}

shinyApp(ui = ui, server = server)
Shiny applications not supported in static R Markdown documents

Conclusion

In this exercise, we: 1- Explored the shiny package and its documentation. 2- Built a basic Shiny app for exploring datasets. 3- Extended the app with a slider to control the number of observations displayed. This demonstrates how Shiny allows you to build interactive web applications quickly and extend them for more complex functionality.