This is my first attempt at using Shiny.
I have a simulated patient-level dataset with 4 variables:
- group: Categorical, takes on values A, B and C. Represents 3 different treatment types that were used in the study.
 - week: Numeric variable, takes on values 1, 4, 8.Represents follow-up week.
 - painscore: Numeric variable, score on scale of 1-10, with 1 indicating no pain, 10 indicating extreme pain.
 - dependscore: Numeric variable, score on scale of 1-10, with 1 indicating no dependency on pain meds, 10 indicating extreme dependency.
 
Trying to build a simple app that accepts two inputs: the week, and the variable, and provides two outputs:
- A boxplot of distribution of scores for the selected variable for the selected week. The x axis would represent the 3 levels of group (A, B and C).
 - A summary table the shows the number of observations, median, 25th percentile, 75th percentile and number of missing.
 
I was able to create the interactive boxplot, but I am unable to create the summary table. I was able to create static versions of this table in RMarkdown using the summaryBy function from doBy, but I am not able to implement it in Shiny. Tried following the advice here and here but I'm missing something.
Here's my code for reproducibility. Excuse the extensive annotations, (I'm a complete beginner) they are more for myself than for anyone else.
#libraries--------------------
library(shiny)
library(tidyverse)
library(knitr)
library(doBy)
#----------------------------
#input data
set.seed(123)
mydf <- data.frame( group     =   rep(rep(c("A","B","C"), each = 3), times = 3),
                    week      =   rep(rep(c(1,4,8), each = 9)),
                    painscore =   sample(1:10, 27, replace = TRUE),
                    dependscore = sample(1:10, 27, replace = TRUE) )
#--------------------------
#define custom function to calculate summary statistics for column of interest. 
#function explained in a little more detail when applied in the server function.
fun <- function(x) { 
    c( n = length(x),
       m = median(x), 
       firstq = round(quantile(x)[2], 1), 
       lastq = round(quantile(x)[4], 1), 
       missing = mean(is.na(x)))
}
#-------------------------
#UI
ui <- fluidPage(
     titlePanel("Shiny Boxplot and Table"),
    #User can provide two different inputs
    sidebarLayout(
        sidebarPanel(
            #1. allow user to pick week using radiobuttons
            radioButtons(inputId = "pickedwk",
                        label = "week you want to display",
                        choices = c(1,4,8),
                        selected = 1), 
            #2. user can pick variable to visualize using dropdownboxes
            selectInput(inputId = "var",
                        label = "variable to visualize",
                        list("How much pain did you feel today?" = "painscore",
                             "How dependent are you on medication?" = "dependscore")), 
            #helpertext
            helpText("Enter week/variable choices here") 
                     ),
     #Spaceholders for output
         mainPanel(
                     plotOutput("boxplot"), #boxplot placeholder
                     htmlOutput("descriptives") #kable html table placeholder
                  )
                )
             )
#-------------------------
#Server
server <- function(input, output) {
    #create dataset that subsets down to the week picked by user.
    weeksub <- reactive({
        mydf %>% filter(week == input$pickedwk[1])
                        }) 
    #1. use reactive datasubset to render boxplot.
    output$boxplot <- renderPlot({ 
        ggplot(weeksub(), aes_string(x = "group", y = input$var)) + #input$var works here
        geom_boxplot(fill = "red", outlier.shape = 15, outlier.color = "black") +
        scale_y_continuous(name = as.character(input$var)) +
        scale_x_discrete(name = "group") +
        ggtitle(paste("Distribution of", as.character(input$var), "by treatment group"))  
    })
    #2. use same reactive datasubset to render kable descriptive statistics for the variable picked.
    output$descriptives <- renderText({
        kable(summaryBy(input$var ~ group, data = as.data.frame(weeksub()), FUN = fun),
      #note: here, I'm using the summaryBy function from package doBy. It takes the form var~ categoricalvar
      # so, either painscore ~ group, or dependscore ~ group depending on what the user picked, and uses
      #my custom function to return a table of count, median, 25th percentile, 75th percentile and missing count for 
      #the 3 levels of the group variable (for A, B, and C)
        col.names = c("Number", "Median", "1Q", "3Q", "Missing"))
    })
}#server function ends
# Run the application 
shinyApp(ui = ui, server = server)