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
## starting httpd help server ... done
## No vignettes found by browseVignettes("shiny")
Step 2: Analyzing the Package Structure Listing Functions and Datasets
## [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)
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)
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.