1

enter image description here

I've got this app for K-Means Clustering. I'd like the user to select a ggplot2 theme using selectInput. The user would look at a dropdown and select one theme for his plot.

Here is what I've tried:


###################################################################################################################
# Shiny App
###################################################################################################################
ui <- navbarPage("Clustering Demo",
                 tabPanel("K-Means", icon = icon("folder-open"),
                          sidebarLayout(
                            sidebarPanel(
                              sliderInput("num_centers", 
                                          label = h4("Select K (# of Clusters)"),
                                          min = 2,
                                          max = 10,
                                          value = 2),
                              selectInput("theme", label = h4("Select theme for plot"),
                                          choices = list("Light" = theme_light(),
                                                         "Minimal" = theme_minimal()))

                            ),
                            mainPanel(
                              plotOutput("kmeans"))
                          )
                 )
)



server <- function(input, output, session) {

  # K-Means Algorithm
  k_centers <- reactive({kmeans(x = harvard_scaled, centers = input$num_centers)})

  plot_theme <- reactive({input$theme})

  output$kmeans <- renderPlot({

    # Require number of centers
    req(input$num_centers)

    # K Means augmented dataset
    harvard_cluster <- augment(k_centers(), harvard_processed)

    # Static Plot 
    harvard_cluster %>% 
      janitor::clean_names() %>% 
      ggplot(aes(nevents, nplay_video, color = cluster)) +
      geom_point() +
      labs(x = "# of interactions with the course",
           y = "# of play video events",
           color = "Cluster") +
      xlim(0, 52000) +
      ylim(0, 12500) +
      ggtitle(paste("K-Means Clustering of students where", "K =", input$num_centers)) +
      plot_theme()
  })

}




# Create Shiny app object
shinyApp(ui = ui, server = server)

Example dataset: harvard_scaled

harvard_scaled <- structure(c(0.150884824647657, 0.150884824647657, 0.449543446630647, 
0.217253407310543, -0.230734525663942, -0.330287399658272, -0.960788934955696, 
0.715017777282194, 0.449543446630647, -0.147773797335334, -0.380063836655437, 
-0.612353875975541, -0.463024564984046, -0.811459623964201, -1.60788261591884, 
-1.60788261591884, -0.89442035229281, 2.04238943053993, 1.7105465172255, 
2.29127161552575, 0.233845552976265, -0.761683186967036, -0.811459623964201, 
-1.12671039161291, -0.147773797335334, 1.19619000158812, 0.980492107933741, 
1.7105465172255, -0.711906749969871, -0.0648130690067253, -0.844643915295645, 
0.217253407310543, -0.570619818667904, -0.570619818667904, -0.990182090888924, 
0.22009369436402, 1.04308122833602, -0.046166978391628, 1.04308122833602, 
-0.677930938293665, -0.725535119180281, -0.509299178881755, -0.509299178881755, 
0.363713087547369, 0.363713087547369, 0.363713087547369, 1.94675381465822, 
1.84993175183798, 1.68856164713759, -1.226589294275, -1.25079480998006, 
-1.28790993406115, -0.892553177545187, 0.704204008465197, 0.591244935174923, 
0.962396175985825, 1.36582143773681, -1.22416874270449, -0.890939476498183, 
-1.09426580842068, 0.970464681220845, -0.691647397193198, 0.567039419469864, 
-0.885291522833669), .Dim = c(32L, 2L), .Dimnames = list(c("Mazda RX4", 
"Mazda RX4 Wag", "Datsun 710", "Hornet 4 Drive", "Hornet Sportabout", 
"Valiant", "Duster 360", "Merc 240D", "Merc 230", "Merc 280", 
"Merc 280C", "Merc 450SE", "Merc 450SL", "Merc 450SLC", "Cadillac Fleetwood", 
"Lincoln Continental", "Chrysler Imperial", "Fiat 128", "Honda Civic", 
"Toyota Corolla", "Toyota Corona", "Dodge Challenger", "AMC Javelin", 
"Camaro Z28", "Pontiac Firebird", "Fiat X1-9", "Porsche 914-2", 
"Lotus Europa", "Ford Pantera L", "Ferrari Dino", "Maserati Bora", 
"Volvo 142E"), c("mpg", "disp")), "`scaled:center`" = c(mpg = 20.090625, 
disp = 230.721875), "`scaled:scale`" = c(mpg = 6.0269480520891, 
disp = 123.938693831382))

Example dataset: harvard_processed

harvard_processed <- structure(list(mpg = c(21, 21, 22.8, 21.4, 18.7, 18.1, 14.3, 
24.4, 22.8, 19.2, 17.8, 16.4, 17.3, 15.2, 10.4, 10.4, 14.7, 32.4, 
30.4, 33.9, 21.5, 15.5, 15.2, 13.3, 19.2, 27.3, 26, 30.4, 15.8, 
19.7, 15, 21.4), disp = c(160, 160, 108, 258, 360, 225, 360, 
146.7, 140.8, 167.6, 167.6, 275.8, 275.8, 275.8, 472, 460, 440, 
78.7, 75.7, 71.1, 120.1, 318, 304, 350, 400, 79, 120.3, 95.1, 
351, 145, 301, 121)), row.names = c("Mazda RX4", "Mazda RX4 Wag", 
"Datsun 710", "Hornet 4 Drive", "Hornet Sportabout", "Valiant", 
"Duster 360", "Merc 240D", "Merc 230", "Merc 280", "Merc 280C", 
"Merc 450SE", "Merc 450SL", "Merc 450SLC", "Cadillac Fleetwood", 
"Lincoln Continental", "Chrysler Imperial", "Fiat 128", "Honda Civic", 
"Toyota Corolla", "Toyota Corona", "Dodge Challenger", "AMC Javelin", 
"Camaro Z28", "Pontiac Firebird", "Fiat X1-9", "Porsche 914-2", 
"Lotus Europa", "Ford Pantera L", "Ferrari Dino", "Maserati Bora", 
"Volvo 142E"), class = "data.frame")
MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • hi, consider using a statement with switch.. ``` b <- switch(input$theme, bw = b + theme_bw(base_size = input$theme_size), grey = b + theme_grey(base_size = input$theme_size).... )``` – lemairev Jan 23 '19 at 21:32
  • Thanks for letting me know @MrFlick . I just added `harvard_scaled` –  Jan 23 '19 at 21:32
  • 1
    Almost, now `harvard_processed` doesn't exist. – MrFlick Jan 23 '19 at 21:36
  • @MrFlick Added `harvard_processed` –  Jan 23 '19 at 21:53
  • These sample data don't work because now they don't match the `aes()` you use in the plotting code. Make sure you test your example in a new R session. But at this point it doesn't really matter any more. My solution should work if you put it into your code. But next time it would have been a lot easier to have a proper [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – MrFlick Jan 23 '19 at 22:02
  • Sorry... its tricky having to replace sensitive, private data with a dummy dataset. Thanks –  Jan 23 '19 at 22:03

1 Answers1

5

If you click the dropdown for the theme select, you'll probably see that it doesn't look like you expect. You can't store non-atomic objects in the UI layer. It would be easier to define a list of themes elsewhere in code and use them as a look up. For example

themes <- list("Light" = theme_light(),
               "Minimal" = theme_minimal())

ui <- navbarPage(..., 
   selectInput("theme", label = h4("Select theme for plot"), choices = names(themes)), 
   ...)

server <- function(input, output, session) {
   ...
   plot_theme <- reactive({themes[[input$theme]]})
   ...
}
MrFlick
  • 195,160
  • 17
  • 277
  • 295