…
2024-12-09
In this exercise, we will explore the functionality of the shiny package, create a basic Shiny app, and extend its functionality with custom inputs and outputs. Shiny is a powerful R package that makes it easy to build interactive web applications directly from R.
# 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
## starting httpd help server ... done
## No vignettes found by browseVignettes("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"
## no data sets found
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)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)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.
In this exercise, we will explore the functionality of the data.table package, which is known for efficient data manipulation in R. We will also extend its functionality by creating custom functions to enhance data handling.
# Display package documentation
?data.table
# List vignettes for the package
browseVignettes("data.table")Step 2: Analyzing the Package Structure
## [1] "%between%" "%chin%" "%flike%"
## [4] "%ilike%" "%inrange%" "%like%"
## [7] "%notin%" "%plike%" ":="
## [10] "[.data.table" "address" "alloc.col"
## [13] "as.data.table" "as.IDate" "as.ITime"
## [16] "as.xts.data.table" "between" "chgroup"
## [19] "chmatch" "chorder" "CJ"
## [22] "copy" "cube" "data.table"
## [25] "dcast" "dcast.data.table" "fcase"
## [28] "fcoalesce" "fdroplevels" "fifelse"
## [31] "fintersect" "first" "format_col"
## [34] "format_list_item" "foverlaps" "frank"
## [37] "frankv" "fread" "frollapply"
## [40] "frollmean" "frollsum" "fsetdiff"
## [43] "fsetequal" "fsort" "funion"
## [46] "fwrite" "getDTthreads" "getNumericRounding"
## [49] "groupingsets" "haskey" "hour"
## [52] "IDateTime" "indices" "inrange"
## [55] "is.data.table" "isoweek" "key"
## [58] "key<-" "last" "let"
## [61] "like" "mday" "melt"
## [64] "melt.data.table" "merge.data.table" "minute"
## [67] "month" "nafill" "quarter"
## [70] "rbindlist" "rleid" "rleidv"
## [73] "rollup" "rowid" "rowidv"
## [76] "second" "set" "setalloccol"
## [79] "setattr" "setcolorder" "setDF"
## [82] "setDT" "setDTthreads" "setindex"
## [85] "setindexv" "setkey" "setkeyv"
## [88] "setnafill" "setnames" "setNumericRounding"
## [91] "setorder" "setorderv" "shift"
## [94] "shouldPrint" "SJ" "substitute2"
## [97] "tables" "test.data.table" "timetaken"
## [100] "transpose" "truelength" "tstrsplit"
## [103] "uniqueN" "update_dev_pkg" "wday"
## [106] "week" "yday" "year"
## [109] "yearmon" "yearqtr"
## no data sets found
Step 3: Solving a Practical Problem
Creating and Manipulating a Data Table We will create a data.table object and perform basic manipulations such as filtering, grouping, and summarizing data.
# Creating a sample data.table
DT <- data.table(
ID = 1:10,
Name = c("John", "Alice", "Bob", "Eve", "Jane", "Tom", "Sara", "Leo", "Paul", "Anna"),
Score = c(85, 90, 88, 70, 95, 60, 78, 80, 85, 92)
)
# Display the data.table
DT## ID Name Score
## <int> <char> <num>
## 1: 1 John 85
## 2: 2 Alice 90
## 3: 3 Bob 88
## 4: 4 Eve 70
## 5: 5 Jane 95
## 6: 6 Tom 60
## 7: 7 Sara 78
## 8: 8 Leo 80
## 9: 9 Paul 85
## 10: 10 Anna 92
## ID Name Score
## <int> <char> <num>
## 1: 1 John 85
## 2: 2 Alice 90
## 3: 3 Bob 88
## 4: 5 Jane 95
## 5: 9 Paul 85
## 6: 10 Anna 92
# Grouping and summarizing: Calculate the average score by the first letter of the Name
DT[, .(Avg_Score = mean(Score)), by = substr(Name, 1, 1)]## substr Avg_Score
## <char> <num>
## 1: J 90
## 2: A 91
## 3: B 88
## 4: E 70
## 5: T 60
## 6: S 78
## 7: L 80
## 8: P 85
Step 4: Extending the Package
Creating a Custom Function Here, we define a function to extend data.table operations by performing both filtering and summarization.
custom_summary <- function(dt, filter_value) {
dt_filtered <- dt[Score > filter_value]
dt_filtered[, .(Avg_Score = mean(Score), Count = .N), by = substr(Name, 1, 1)]
}
# Applying the custom function
custom_summary(DT, 80)## substr Avg_Score Count
## <char> <num> <int>
## 1: J 90 2
## 2: A 91 2
## 3: B 88 1
## 4: P 85 1
Conclusion In this exercise, we:
1-plored the data.table package and its documentation. 2-eated and manipulated a data.table object with basic data manipulation operations. 3-veloped and applied a custom function to perform filtering and summarization. This demonstrates the powerful capabilities of data.table for fast and flexible data manipulation in R.