These exercises are about building basic apps, app layouts, and themes.

Exercises for Shiny session 1

  1. Make an app that reads in the table in the ‘data’ folder of the course materials that has a file name of ‘msk_2024_clinical_Pancreatic_rev.csv’ and displays that table on the page.
library(ggplot2)
library(dplyr)
library(shiny)
library(bslib)
library(DT)
library(survival)


data_in <- rio::import("data/msk_2024_clinical_Pancreatic_rev.csv")

ui <- page_fluid(
  card(
    card_header("Clinical Data"),
    DT::dataTableOutput("data_in")
    )
)

server <- function(input, output){
  
  output$data_in <- renderDataTable({
    datatable(data_in)
  })
  
  
}
shinyApp(ui, server)

  1. Add some figures to the page, including a plot that:
# SAMPLE CODE FOR PLOTS:

data_in <- rio::import("data/msk_2024_clinical_Pancreatic_rev.csv")

# Sample code for pie chart:
library(ggplot2)
library(dplyr)

data_in %>%
  group_by(Sex) %>%
  summarize(Num = n()) %>%
  ggplot(aes(x = 1, y = Num, fill = Sex)) +
  geom_bar(stat="identity", color="white") +
  coord_polar("y") + theme_void()

# Sample code for histogram:
ggplot(data_in, aes(x = Current_Age)) +
      geom_histogram(bins=10) + 
      theme_bw()

# Sample code for survival analysis:
library(survival)

surv_obj <- Surv(time = data_in$Overall_Survival_Months, event = data_in$Survival_code)
fit <- survfit(surv_obj ~ Smoking_History_NLP, data = data_in)
surv_df <- data.frame(
  time = fit$time,
  surv = fit$surv,
  group = rep(names(fit$strata), fit$strata)
)

ggplot(surv_df, aes(x = time, y = surv, color = group)) +
  geom_step(linewidth = 1) +
  labs(x = "Time (months)", y = "Survival Probability", color = "Group") +
  theme_minimal()
library(ggplot2)
library(dplyr)
library(shiny)
library(bslib)
library(DT)
library(survival)

data_in <- rio::import("data/msk_2024_clinical_Pancreatic_rev.csv")

surv_obj <- Surv(time = data_in$Overall_Survival_Months, event = data_in$Survival_code)
fit_smokes <- survfit(surv_obj ~ Smoking_History_NLP, data = data_in)
surv_df <- data.frame(
  time = fit_smokes$time,
  surv = fit_smokes$surv,
  group = rep(names(fit_smokes$strata), fit_smokes$strata)
)

ui <- page_fluid(
  card(
    card_header("Clinical Data"),
    DT::dataTableOutput("data_in")),
  card(card_header("Age distribution"),
       plotOutput("age_histogram")),
  card(card_header("Smoking status effect on survival"),
       plotOutput("smokes_kaplan")),
  card(card_header("Sex"),
       plotOutput("sex_pie_chart")),
  card(card_header("Smoking status"),
       plotOutput("smokes_pie_chart")),
  card(card_header("Sample Type"),
       plotOutput("sampleType_pie_chart")),
  card(card_header("Cancer Type"),
       plotOutput("cancerType_pie_chart"))
)

server <- function(input, output){
  
  output$data_in <- renderDataTable({
    datatable(data_in)
  })
  
  output$age_histogram <- renderPlot({
    ggplot(data_in, aes(x = Current_Age)) +
      geom_histogram(bins=10) + 
      theme_bw()
  })
  
  
  output$sex_pie_chart <- renderPlot({
    data_in %>%
      group_by(Sex) %>%
      summarize(Num = n()) %>%
      ggplot(aes(x = 1, y = Num, fill = Sex)) +
      geom_bar(stat="identity", color="white") +
      coord_polar("y") + theme_void()
  })
  
  output$sampleType_pie_chart <- renderPlot({
    data_in %>%
      group_by(Sample_Type) %>%
      summarize(Num = n()) %>%
      ggplot(aes(x = 1, y = Num, fill = Sample_Type)) +
      geom_bar(stat="identity", color="white") +
      coord_polar("y") + theme_void()
  })
  
  output$smokes_pie_chart <- renderPlot({
    data_in %>%
      group_by(Smoking_History_NLP) %>%
      summarize(Num = n()) %>%
      ggplot(aes(x = 1, y = Num, fill = Smoking_History_NLP)) +
      geom_bar(stat="identity", color="white") +
      coord_polar("y") + theme_void()
  })
  
  output$cancerType_pie_chart <- renderPlot({
    data_in %>%
      group_by(Cancer_Type_Detailed) %>%
      summarize(Num = n()) %>%
      ggplot(aes(x = 1, y = Num, fill = Cancer_Type_Detailed)) +
      geom_bar(stat="identity", color="white") +
      coord_polar("y") + theme_void()
  })
  output$smokes_kaplan <- renderPlot({
    ggplot(surv_df, aes(x = time, y = surv, color = group)) +
      geom_step(linewidth = 1) +
      labs(x = "Time (months)", y = "Survival Probability", color = "Group") +
      theme_minimal()
  })
  
}
shinyApp(ui, server)

  1. Make the app have multiple pages, with the first page containing all of the plots and the second page containing the table.
library(ggplot2)
library(dplyr)
library(shiny)
library(bslib)
library(DT)
library(survival)


data_in <- rio::import("data/msk_2024_clinical_Pancreatic_rev.csv")

surv_obj <- Surv(time = data_in$Overall_Survival_Months, event = data_in$Survival_code)
fit_smokes <- survfit(surv_obj ~ Smoking_History_NLP, data = data_in)
surv_df <- data.frame(
  time = fit_smokes$time,
  surv = fit_smokes$surv,
  group = rep(names(fit_smokes$strata), fit_smokes$strata)
)


ui <- page_navbar(
  title = "Cancer data",
  theme = bs_theme(version = 5, bootswatch = "pulse"),
  nav_panel(
    title = "Data visualization",
    
    layout_columns(
      layout_columns(
        value_box("Number of patients", 
                  value = nrow(data_in),
                  theme = "text-purple"),
        card(card_header("Age distribution"),
             plotOutput("age_histogram")),
        col_widths = c(3,9), 
        row_heights = list("300px")
      ),
      layout_columns(
        card(card_header("Sex"),
             plotOutput("sex_pie_chart")),
        card(card_header("Smoking status"),
             plotOutput("smokes_pie_chart")),
        card(card_header("Sample Type"),
             plotOutput("sampleType_pie_chart")),
        card(card_header("Cancer Type"),
             plotOutput("cancerType_pie_chart")),
        col_widths = c(6, 6, 6, 6),
        row_heights = c("400px", "400px")
      ),
      layout_columns(
        card(card_header("Survival by group"),
             plotOutput("smokes_kaplan")),
        col_widths = c(12), 
        row_heights = list("500px")
      ),
      col_widths = c(12,12, 12), fill=F
    )
    
  ),
  nav_panel(
    title = "Clinical data table",
    card(
      card_header("Clinical Data"),
      DT::dataTableOutput("data_in")
    )
  ),
  nav_spacer(),
  nav_menu(
    title = "Links",
    align = "right",
    nav_item(
      tags$a(
        shiny::icon("chart-simple"), "RU BRC - Learn more!",
        href = "https://www.cbioportal.org/",
        target = "_blank"
      )
    )
  )
)

server <- function(input, output){
  
  output$data_in <- renderDataTable({
    datatable(data_in)
  })
  
  output$age_histogram <- renderPlot({
    ggplot(data_in, aes(x = Current_Age)) +
      geom_histogram(bins=10) + 
      theme_bw()
  }) 
  
  
  output$sex_pie_chart <- renderPlot({
    data_in %>%
      group_by(Sex) %>%
      summarize(Num = n()) %>%
      ggplot(aes(x = 1, y = Num, fill = Sex)) +
      geom_bar(stat="identity", color="white") +
      coord_polar("y") + theme_void()
  })
  
  output$sampleType_pie_chart <- renderPlot({
    data_in %>%
      group_by(Sample_Type) %>%
      summarize(Num = n()) %>%
      ggplot(aes(x = 1, y = Num, fill = Sample_Type)) +
      geom_bar(stat="identity", color="white") +
      coord_polar("y") + theme_void()
  })
  
  output$smokes_pie_chart <- renderPlot({
    data_in %>%
      group_by(Smoking_History_NLP) %>%
      summarize(Num = n()) %>%
      ggplot(aes(x = 1, y = Num, fill = Smoking_History_NLP)) +
      geom_bar(stat="identity", color="white") +
      coord_polar("y") + theme_void()
  })
  
  output$cancerType_pie_chart <- renderPlot({
    data_in %>%
      group_by(Cancer_Type_Detailed) %>%
      summarize(Num = n()) %>%
      ggplot(aes(x = 1, y = Num, fill = Cancer_Type_Detailed)) +
      geom_bar(stat="identity", color="white") +
      coord_polar("y") + theme_void()
  })
  
  output$smokes_kaplan <- renderPlot({
    ggplot(surv_df, aes(x = time, y = surv, color = group)) +
      geom_step(linewidth = 1) +
      labs(x = "Time (months)", y = "Survival Probability", color = "Group") +
      theme_minimal()
  })
  
  
}
shinyApp(ui, server)