R package exploration 2

2024-12-09

Introduction In this exercise, we will explore the functionality of the shiny package, create a simple interactive web application using its functions, and extend its functionality with a custom function. The shiny package is widely used in R for building interactive applications that can be deployed on the web.

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.4.2

Exploring the Package Documentation

# Display package documentation
?shiny
## starting httpd help server ... done
# List vignettes for the package
browseVignettes("shiny")
## No vignettes found by browseVignettes("shiny")

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"
# Note: shiny doesn't provide datasets in the same way as other packages like ggplot2
# So, this step is generally less relevant for shiny.

Step 3: Solving a Practical Problem Creating a Simple Interactive Application We will create a simple shiny app that allows users to input a number and then squares that number. The app will update interactively based on the user’s input.

# Define UI for the application
ui <- fluidPage(
  titlePanel("Square a Number"),
  sidebarLayout(
    sidebarPanel(
      numericInput("num", "Enter a number:", value = 1),
      actionButton("submit", "Submit")
    ),
    mainPanel(
      textOutput("result")
    )
  )
)

# Define server logic to square the number
server <- function(input, output) {
  observeEvent(input$submit, {
    result <- input$num^2
    output$result <- renderText({
      paste("The square of", input$num, "is", result)
    })
  })
}

# 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 for Reusability We will define a custom function that takes a number as input and returns its square. This function will be used inside the server logic.

# Define a custom function to square a number
square_number <- function(x) {
  return(x^2)
}

# Modify the server to use the custom function
server <- function(input, output) {
  observeEvent(input$submit, {
    result <- square_number(input$num)
    output$result <- renderText({
      paste("The square of", input$num, "is", result)
    })
  })
}

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

Conclusion In this exercise, we:

Explored the shiny package and its documentation. Created a simple interactive web application that squares a number. Developed and applied a custom function (square_number) to enhance the app’s functionality. This process demonstrates the power and flexibility of R packages for building interactive applications and the ability to extend them with custom logic to meet specific needs.