…
2024-12-09
In this exercise, we will explore the functionality of the shiny package, create an interactive web application using its tools, and extend its functionality with custom components. The shiny package is part of the RStudio ecosystem and is widely used for building interactive web applications directly in 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"
We will create a simple Shiny app that lets users interactively plot a subset of the built-in mtcars dataset.
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)
Adding Custom Features We will enhance the app by allowing the user to filter rows based on mtcars variables.
# Load required packages
library(shiny)
library(ggplot2) # Ensure ggplot2 is loaded
# Updated UI with filtering options
ui <- fluidPage(
titlePanel("Enhanced MTCARS App"),
sidebarLayout(
sidebarPanel(
selectInput("xvar", "X-axis variable:", choices = names(mtcars)),
selectInput("yvar", "Y-axis variable:", choices = names(mtcars)),
sliderInput("pointSize", "Point Size:", min = 1, max = 10, value = 3),
sliderInput("cylFilter", "Number of Cylinders:",
min = min(mtcars$cyl), max = max(mtcars$cyl),
value = c(min(mtcars$cyl), max(mtcars$cyl)))
),
mainPanel(
plotOutput("scatterPlot")
)
)
)
# Updated Server with filtering logic
server <- function(input, output) {
filteredData <- reactive({
mtcars[mtcars$cyl >= input$cylFilter[1] & mtcars$cyl <= input$cylFilter[2], ]
})
output$scatterPlot <- renderPlot({
ggplot(filteredData(), aes_string(x = input$xvar, y = input$yvar)) +
geom_point(size = input$pointSize, color = "blue") +
theme_minimal() +
labs(
title = paste("Scatter Plot of", input$yvar, "vs", input$xvar),
x = input$xvar,
y = input$yvar
)
})
}
# Run the enhanced app
shinyApp(ui = ui, server = server)
In this exercise, we:
Explored the shiny package and its documentation. Created a basic interactive app using shiny. Extended the app to include filtering and custom interactivity. This exercise demonstrates the ability of the shiny package to build interactive and responsive applications for data analysis and visualization.
# Install data.table (if not already installed)
if (!requireNamespace("data.table", quietly = TRUE)) {
install.packages("data.table")
}
library(data.table)
## [1] "%+%" "%+replace%"
## [3] "aes" "aes_"
## [5] "aes_all" "aes_auto"
## [7] "aes_q" "aes_string"
## [9] "after_scale" "after_stat"
## [11] "alpha" "annotate"
## [13] "annotation_custom" "annotation_logticks"
## [15] "annotation_map" "annotation_raster"
## [17] "arrow" "as_label"
## [19] "as_labeller" "autolayer"
## [21] "autoplot" "AxisSecondary"
## [23] "benchplot" "binned_scale"
## [25] "borders" "calc_element"
## [27] "combine_vars" "continuous_scale"
## [29] "Coord" "coord_cartesian"
## [31] "coord_equal" "coord_fixed"
## [33] "coord_flip" "frank"
## [35] "coord_munch" "coord_polar"
## [37] "coord_quickmap" "coord_sf"
## [39] "coord_trans" "CoordCartesian"
## [41] "CoordFixed" "CoordFlip"
## [43] "CoordMap" "CoordPolar"
## [45] "CoordQuickmap" "CoordSf"
## [47] "CoordTrans" "cut_interval"
## [49] "cut_number" "cut_width"
## [51] "datetime_scale" "derive"
## [53] "diamonds" "discrete_scale"
## [55] "draw_key_abline" "draw_key_blank"
## [57] "draw_key_boxplot" "draw_key_crossbar"
## [59] "draw_key_dotplot" "draw_key_label"
## [61] "draw_key_linerange" "draw_key_path"
## [63] "draw_key_point" "draw_key_pointrange"
## [65] "draw_key_polygon" "draw_key_rect"
## [67] "draw_key_smooth" "draw_key_text"
## [69] "draw_key_timeseries" "draw_key_vline"
## [71] "draw_key_vpath" "dup_axis"
## [73] "economics" "economics_long"
## [75] "el_def" "element_blank"
## [77] "element_grob" "element_line"
## [79] "element_rect" "element_render"
## [81] "element_text" "enexpr"
## [83] "enexprs" "enquo"
## [85] "enquos" "ensym"
## [87] "ensyms" "expand_limits"
## [89] "expand_scale" "expansion"
## [91] "expr" "Facet"
## [93] "facet_grid" "facet_null"
## [95] "facet_wrap" "FacetGrid"
## [97] "FacetNull" "FacetWrap"
## [99] "faithfuld" "find_panel"
## [101] "flip_data" "flipped_names"
## [103] "fortify" "Geom"
## [105] "geom_abline" "geom_area"
## [107] "geom_bar" "geom_bin_2d"
## [109] "geom_bin2d" "geom_blank"
## [111] "geom_boxplot" "geom_col"
## [113] "geom_contour" "geom_contour_filled"
## [115] "geom_count" "geom_crossbar"
## [117] "geom_curve" "geom_density"
## [119] "geom_density_2d" "geom_density_2d_filled"
## [121] "geom_density2d" "geom_density2d_filled"
## [123] "geom_dotplot" "geom_errorbar"
## [125] "geom_errorbarh" "geom_freqpoly"
## [127] "geom_function" "geom_hex"
## [129] "geom_histogram" "geom_hline"
## [131] "geom_jitter" "geom_label"
## [133] "geom_line" "geom_linerange"
## [135] "geom_map" "geom_path"
## [137] "geom_point" "geom_pointrange"
## [139] "geom_polygon" "geom_qq"
## [141] "geom_qq_line" "geom_quantile"
## [143] "geom_raster" "geom_rect"
## [145] "geom_ribbon" "geom_rug"
## [147] "geom_segment" "geom_sf"
## [149] "geom_sf_label" "geom_sf_text"
## [151] "geom_smooth" "geom_spoke"
## [153] "geom_step" "geom_text"
## [155] "geom_tile" "geom_violin"
## [157] "geom_vline" "GeomAbline"
## [159] "GeomAnnotationMap" "GeomArea"
## [161] "GeomBar" "GeomBlank"
## [163] "GeomBoxplot" "GeomCol"
## [165] "GeomContour" "GeomContourFilled"
## [167] "GeomCrossbar" "GeomCurve"
## [169] "GeomCustomAnn" "GeomDensity"
## [171] "GeomDensity2d" "GeomDensity2dFilled"
## [173] "GeomDotplot" "GeomErrorbar"
## [175] "GeomErrorbarh" "GeomFunction"
## [177] "GeomHex" "GeomHline"
## [179] "GeomLabel" "GeomLine"
## [181] "GeomLinerange" "GeomLogticks"
## [183] "GeomMap" "GeomPath"
## [185] "GeomPoint" "GeomPointrange"
## [187] "GeomPolygon" "GeomQuantile"
## [189] "GeomRaster" "GeomRasterAnn"
## [191] "GeomRect" "GeomRibbon"
## [193] "GeomRug" "GeomSegment"
## [195] "GeomSf" "GeomSmooth"
## [197] "GeomSpoke" "GeomStep"
## [199] "GeomText" "GeomTile"
## [201] "GeomViolin" "GeomVline"
## [203] "get_alt_text" "get_element_tree"
## [205] "gg_dep" "ggplot"
## [207] "ggplot_add" "ggplot_build"
## [209] "ggplot_gtable" "ggplotGrob"
## [211] "ggproto" "ggproto_parent"
## [213] "ggsave" "ggtitle"
## [215] "guide_axis" "guide_bins"
## [217] "guide_colorbar" "guide_colorsteps"
## [219] "guide_colourbar" "guide_coloursteps"
## [221] "guide_gengrob" "guide_geom"
## [223] "guide_legend" "guide_merge"
## [225] "guide_none" "guide_train"
## [227] "guide_transform" "guides"
## [229] "has_flipped_aes" "is.Coord"
## [231] "is.facet" "is.ggplot"
## [233] "is.ggproto" "is.theme"
## [235] "label_both" "label_bquote"
## [237] "label_context" "label_parsed"
## [239] "label_value" "label_wrap_gen"
## [241] "labeller" "labs"
## [243] "last_plot" "layer"
## [245] "layer_data" "layer_grob"
## [247] "layer_scales" "layer_sf"
## [249] "Layout" "lims"
## [251] "luv_colours" "map_data"
## [253] "margin" "max_height"
## [255] "max_width" "mean_cl_boot"
## [257] "mean_cl_normal" "mean_sdl"
## [259] "mean_se" "median_hilow"
## [261] "merge_element" "midwest"
## [263] "mpg" "msleep"
## [265] "panel_cols" "panel_rows"
## [267] "Position" "position_dodge"
## [269] "position_dodge2" "position_fill"
## [271] "position_identity" "position_jitter"
## [273] "position_jitterdodge" "position_nudge"
## [275] "position_stack" "PositionDodge"
## [277] "PositionDodge2" "PositionFill"
## [279] "PositionIdentity" "PositionJitter"
## [281] "PositionJitterdodge" "PositionNudge"
## [283] "PositionStack" "presidential"
## [285] "qplot" "quickplot"
## [287] "quo" "quo_name"
## [289] "quos" "register_theme_elements"
## [291] "rel" "remove_missing"
## [293] "render_axes" "render_strips"
## [295] "reset_theme_settings" "resolution"
## [297] "Scale" "scale_alpha"
## [299] "scale_alpha_binned" "scale_alpha_continuous"
## [301] "scale_alpha_date" "scale_alpha_datetime"
## [303] "scale_alpha_discrete" "scale_alpha_identity"
## [305] "scale_alpha_manual" "scale_alpha_ordinal"
## [307] "scale_color_binned" "scale_color_brewer"
## [309] "scale_color_continuous" "scale_color_date"
## [311] "scale_color_datetime" "scale_color_discrete"
## [313] "scale_color_distiller" "scale_color_fermenter"
## [315] "scale_color_gradient" "scale_color_gradient2"
## [317] "scale_color_gradientn" "scale_color_grey"
## [319] "scale_color_hue" "scale_color_identity"
## [321] "scale_color_manual" "scale_color_ordinal"
## [323] "scale_color_steps" "scale_color_steps2"
## [325] "scale_color_stepsn" "scale_color_viridis_b"
## [327] "scale_color_viridis_c" "scale_color_viridis_d"
## [329] "scale_colour_binned" "scale_colour_brewer"
## [331] "scale_colour_continuous" "scale_colour_date"
## [333] "scale_colour_datetime" "scale_colour_discrete"
## [335] "scale_colour_distiller" "scale_colour_fermenter"
## [337] "scale_colour_gradient" "scale_colour_gradient2"
## [339] "scale_colour_gradientn" "scale_colour_grey"
## [341] "scale_colour_hue" "scale_colour_identity"
## [343] "scale_colour_manual" "scale_colour_ordinal"
## [345] "scale_colour_steps" "scale_colour_steps2"
## [347] "scale_colour_stepsn" "scale_colour_viridis_b"
## [349] "scale_colour_viridis_c" "scale_colour_viridis_d"
## [351] "scale_continuous_identity" "scale_discrete_identity"
## [353] "scale_discrete_manual" "scale_fill_binned"
## [355] "scale_fill_brewer" "scale_fill_continuous"
## [357] "scale_fill_date" "scale_fill_datetime"
## [359] "scale_fill_discrete" "scale_fill_distiller"
## [361] "scale_fill_fermenter" "scale_fill_gradient"
## [363] "scale_fill_gradient2" "scale_fill_gradientn"
## [365] "scale_fill_grey" "scale_fill_hue"
## [367] "scale_fill_identity" "scale_fill_manual"
## [369] "scale_fill_ordinal" "scale_fill_steps"
## [371] "scale_fill_steps2" "scale_fill_stepsn"
## [373] "scale_fill_viridis_b" "scale_fill_viridis_c"
## [375] "scale_fill_viridis_d" "scale_linetype"
## [377] "scale_linetype_binned" "scale_linetype_continuous"
## [379] "scale_linetype_discrete" "scale_linetype_identity"
## [381] "scale_linetype_manual" "scale_linewidth"
## [383] "scale_linewidth_binned" "scale_linewidth_continuous"
## [385] "scale_linewidth_date" "scale_linewidth_datetime"
## [387] "scale_linewidth_discrete" "scale_linewidth_identity"
## [389] "scale_linewidth_manual" "scale_linewidth_ordinal"
## [391] "scale_radius" "scale_shape"
## [393] "scale_shape_binned" "scale_shape_continuous"
## [395] "scale_shape_discrete" "scale_shape_identity"
## [397] "scale_shape_manual" "scale_shape_ordinal"
## [399] "scale_size" "scale_size_area"
## [401] "scale_size_binned" "scale_size_binned_area"
## [403] "scale_size_continuous" "scale_size_date"
## [405] "scale_size_datetime" "scale_size_discrete"
## [407] "scale_size_identity" "scale_size_manual"
## [409] "scale_size_ordinal" "scale_type"
## [411] "scale_x_binned" "scale_x_continuous"
## [413] "scale_x_date" "scale_x_datetime"
## [415] "scale_x_discrete" "scale_x_log10"
## [417] "scale_x_reverse" "scale_x_sqrt"
## [419] "scale_x_time" "scale_y_binned"
## [421] "scale_y_continuous" "scale_y_date"
## [423] "scale_y_datetime" "scale_y_discrete"
## [425] "scale_y_log10" "scale_y_reverse"
## [427] "scale_y_sqrt" "scale_y_time"
## [429] "ScaleBinned" "ScaleBinnedPosition"
## [431] "ScaleContinuous" "ScaleContinuousDate"
## [433] "ScaleContinuousDatetime" "ScaleContinuousIdentity"
## [435] "ScaleContinuousPosition" "ScaleDiscrete"
## [437] "ScaleDiscreteIdentity" "ScaleDiscretePosition"
## [439] "seals" "sec_axis"
## [441] "set_last_plot" "sf_transform_xy"
## [443] "should_stop" "stage"
## [445] "standardise_aes_names" "stat"
## [447] "Stat" "stat_align"
## [449] "stat_bin" "stat_bin_2d"
## [451] "stat_bin_hex" "stat_bin2d"
## [453] "stat_binhex" "stat_boxplot"
## [455] "stat_contour" "stat_contour_filled"
## [457] "stat_count" "stat_density"
## [459] "stat_density_2d" "stat_density_2d_filled"
## [461] "stat_density2d" "stat_density2d_filled"
## [463] "stat_ecdf" "stat_ellipse"
## [465] "stat_function" "stat_identity"
## [467] "stat_qq" "stat_qq_line"
## [469] "stat_quantile" "stat_sf"
## [471] "stat_sf_coordinates" "stat_smooth"
## [473] "stat_spoke" "stat_sum"
## [475] "stat_summary" "stat_summary_2d"
## [477] "stat_summary_bin" "stat_summary_hex"
## [479] "stat_summary2d" "stat_unique"
## [481] "stat_ydensity" "StatAlign"
## [483] "StatBin" "StatBin2d"
## [485] "StatBindot" "StatBinhex"
## [487] "StatBoxplot" "StatContour"
## [489] "StatContourFilled" "StatCount"
## [491] "StatDensity" "StatDensity2d"
## [493] "StatDensity2dFilled" "StatEcdf"
## [495] "StatEllipse" "StatFunction"
## [497] "StatIdentity" "StatQq"
## [499] "StatQqLine" "StatQuantile"
## [501] "StatSf" "StatSfCoordinates"
## [503] "StatSmooth" "StatSum"
## [505] "StatSummary" "StatSummary2d"
## [507] "StatSummaryBin" "StatSummaryHex"
## [509] "StatUnique" "StatYdensity"
## [511] "summarise_coord" "summarise_layers"
## [513] "summarise_layout" "sym"
## [515] "syms" "theme"
## [517] "theme_bw" "theme_classic"
## [519] "theme_dark" "theme_get"
## [521] "theme_gray" "theme_grey"
## [523] "theme_light" "theme_linedraw"
## [525] "theme_minimal" "theme_replace"
## [527] "theme_set" "theme_test"
## [529] "theme_update" "theme_void"
## [531] "transform_position" "txhousing"
## [533] "unit" "update_geom_defaults"
## [535] "update_labels" "update_stat_defaults"
## [537] "vars" "waiver"
## [539] "wrap_dims" "xlab"
## [541] "xlim" "ylab"
## [543] "ylim" "zeroGrob"
We will create a sample data.table to demonstrate basic functionality.
# Create a sample data.table
dt <- data.table(
ID = 1:10,
Name = c("Alice", "Bob", "Charlie", "David", "Ella", "Frank", "Grace", "Hannah", "Ivy", "Jack"),
Age = sample(20:50, 10, replace = TRUE),
Score = sample(50:100, 10, replace = TRUE)
)
# View the data.table
print(dt)
## ID Name Age Score
## <int> <char> <int> <int>
## 1: 1 Alice 35 50
## 2: 2 Bob 46 99
## 3: 3 Charlie 26 57
## 4: 4 David 40 95
## 5: 5 Ella 42 86
## 6: 6 Frank 24 93
## 7: 7 Grace 36 50
## 8: 8 Hannah 33 97
## 9: 9 Ivy 28 95
## 10: 10 Jack 39 74
Here, we define a function to calculate and append summary statistics to a data.table.
# Load the data.table library
library(data.table)
# Create a sample data.table
dt <- data.table(
ID = 1:10,
Name = c("Alice", "Bob", "Charlie", "David", "Ella", "Frank", "Grace", "Hannah", "Ivy", "Jack"),
Age = sample(20:50, 10, replace = TRUE),
Score = sample(50:100, 10, replace = TRUE)
)
# Create the Grade column
dt[, Grade := ifelse(Score >= 75, "Pass", "Fail")]
# Verify the data.table structure
print("Original Data Table:")
## [1] "Original Data Table:"
## ID Name Age Score Grade
## <int> <char> <int> <int> <char>
## 1: 1 Alice 47 60 Fail
## 2: 2 Bob 29 53 Fail
## 3: 3 Charlie 33 76 Pass
## 4: 4 David 40 63 Fail
## 5: 5 Ella 24 58 Fail
## 6: 6 Frank 35 57 Fail
## 7: 7 Grace 38 72 Fail
## 8: 8 Hannah 28 58 Fail
## 9: 9 Ivy 50 74 Fail
## 10: 10 Jack 30 86 Pass
# Define the custom function
append_summary <- function(dt, group_col, value_col) {
summary_dt <- dt[, .(
Mean = mean(get(value_col), na.rm = TRUE),
Median = median(get(value_col), na.rm = TRUE),
SD = sd(get(value_col), na.rm = TRUE)
), by = group_col]
return(summary_dt)
}
# Applying the custom function
summary_dt <- append_summary(dt, group_col = "Grade", value_col = "Score")
# Print the resulting summary
print("Summary Data Table:")
## [1] "Summary Data Table:"
## Grade Mean Median SD
## <char> <num> <num> <num>
## 1: Fail 61.875 59 7.434235
## 2: Pass 81.000 81 7.071068
In this exercise, we:
Explored the data.table package and its documentation. Demonstrated key operations like filtering, aggregation, and column manipulation. Developed a custom function to extend its functionality. Highlighted the package’s efficiency with performance benchmarking. This process showcases the power of data.table for efficient and scalable data manipulation in R, making it a go-to package for handling large datasets with ease.