RSesom RSesom - 2 months ago 45
R Question

Checkboxgroupinput in R Shiny with Plotly

Love all the help here so far, but having to teach myself R / Shiny, with no one in the office to help, I am unfortunately stuck again!!

I am trying to do checkboxgroups in Shiny. I read quite a bit, for example this, this, this, this and this already helped, but I am stuck now.

So my data set "ConversionsCompletions" looks now something like this :

date | goal1completions | goal
--------------------------------------------
01012016 | 4 | goal1
01012016 | 10 | goal2
01012016 | 8 | goal3
01012016 | 13 | goal4
02012016 | 6 | goal1
02012016 | 7 | goal2
.....


ui:

checkboxGroupInput("checkGroup", label = h3("Goal"),
choices = c("Goal 1" = "goal1",
"Goal 2" = "goal2",
"Goal 3" = "goal3",
"Goal 4" = "goal4",
"Goal 5" = "goal5",
"Goal 6" = "goal6",
"Goal 7" = "goal7"),
selected = "Goal 1")

plotlyOutput("Conversionrate1")


server:

filteredData <- reactive({

filter(ConversionsCompletions[ConversionsCompletions$goal %in% input$checkGroup,])
})


output$Conversionrate1 <- renderPlotly({
plot_ly(filteredData(), x = ConversionsCompletions$date, y = ConversionsCompletions$goal1Completions, mode = "lines + markers", hoverinfo = y)


})


There is a graph, but it doesn't change when I switch boxes, or shows more than one line at a time. I know usually you need to add the "add_trace" code for plotly charts, so I am not sure how to do it in this case when sometimes there is one line and sometimes multiple.

Any help appreciated!!

Answer

To render a graph properly, you have to use filteredData() and slightly change syntax.

As the first parameter data you should use the filtered dataset and then for x and y variables the appropriate names with a prefix ~.

To plot multiple lines you can use another parameter split. I had to change hoverinfo = y to hoverinfo = "y" otherwise it didn't work (I have the newest version of plotly)

plot_ly(
      data = filteredData(),  
      x = ~date,
      y = ~goal1completions,
      split = ~goal,
      mode = "lines + markers",
      hoverinfo = "y" # "y" instead of y ... at least in the newest version
    ) 

I also used setNames function to make the code for checkboxGroupInput shorter.

setNames(object = paste0("goal", 1:7), 
         nm = paste0("Goal ", 1:7))

You don't need the dplyr function filter for subsetting - at least in this in this case.


EDITED:

I converted the numeric variable date into a date format:

ConversionsCompletions <- read.table("~/Downloads/data", header = T)
d <- as.character(ConversionsCompletions$date)
d <-  paste0(substr(d, 0, 2), "-", substr(d, 3, 4), "-", substr(d, start = 4,          7))
ConversionsCompletions$date <- as.Date(d, format = "%d-%m-%Y")

Full example:

library(shiny)
library(plotly)

rm(ui) ; rm(server)

# use example data
ConversionsCompletions <- read.table("~/Downloads/data", header = T)
d <- as.character(ConversionsCompletions$date)
d <-  paste0(substr(d, 0, 2), "-", substr(d, 3, 4), "-", substr(d, start = 4, 7))
ConversionsCompletions$date <- as.Date(d, format = "%d-%m-%Y")

ui <- fluidPage(
  checkboxGroupInput("checkGroup", label = h3("Goal"), 
                     setNames(object = paste0("goal", 1:7), 
                              nm = paste0("Goal ", 1:7)),
                     selected = "Goal 1"),
  plotlyOutput("Conversionrate1")
)

server <- function(input, output) { 

  filteredData <- reactive({ 
    # no need for "filter"
    ConversionsCompletions[ConversionsCompletions$goal %in% input$checkGroup, ]
  })


  output$Conversionrate1 <- renderPlotly({
    # use filteredData() instead of the full dataset
    plot_ly(
      filteredData(),  
      x = ~date,
      y = ~goal1completions,
      split = ~goal,
      mode = "lines + markers",
      hoverinfo = "y" # "y" instead of y ... at least in the newest version
    ) 
  })
}

shinyApp(ui, server)

enter image description here