lundi 16 novembre 2020

Shiny & Plotly reactive amount rows in subplots based on length of CheckBoxGroupButtons (ERROR: (list) object cannot be coerced to type 'double')

Any help would be greatly appreciated I've been struggling with this for a while. Reprex below.

I'm trying to make plotly::subplot(nrows = ?) with shiny checkbox inputs.

The inputs are datasets so they all have different Y-values but will be plotted along the same X-axis, hence the shareX = TRUE.

I am able to plot the traces if I specify nrow = 3 and all the boxes are checked but I want it to be conditional on the number of inputs selected. Only two inputs selected? Plot two rows. Only one input selected? Don't even use subplot. That's why I included nrows = length(input$choices). And that works when all three are checked!

But it is not working when I split it up into "if else" statements to specify whether I want the subplot or not, AND its not working when I check n < 3 inputs.

Instead I've gotten the error: (list) object cannot be coerced to type 'double'

I believe the error is coming from how the conditional statement is interpreting the length(input$choices) and or how subplot is interpreting the list of traces to plot.

library(shiny)
library(plotly)
library(dplyr)
library(tidyverse)

ui <- fluidPage(
    
    sidebarLayout(
        sidebarPanel(
            checkboxGroupInput("choices",
                        "Inputs:",
                        choices = c("Three", "Four", "Five"))
        ),

        mainPanel(
           plotlyOutput("distPlot")
        )
    )
)

server <- function(input, output) {
    gear5 <- reactive({
        req("Five" %in% input$choices)
    mtcars %>% filter(gear == 5)})
    
    gear4 <- reactive({
        req("Four" %in% input$choices)
        mtcars %>% filter(gear == 4)})
    
    gear3 <- reactive({
        req("Three" %in% input$choices)
        mtcars %>% filter(gear == 3)})
    
    output$distPlot <- renderPlotly({
        if (length(input$choices) > 1) {
        fig <- plot_ly() %>% add_trace(data = gear3(), x = gear3()$mpg, y = gear3()$disp, type = "scatter", mode = "lines") %>% 
                add_trace(data = gear4(), x = gear4()$mpg, y = gear4()$wt, type = "scatter", mode = "lines") %>% 
                add_trace(data = gear5(), x = gear5()$mpg, y = gear5()$qsec, type = "scatter", mode = "lines") 
        
        subplot(fig, shareX = TRUE, nrows = length(input$choices))

        }
        else if (length(input$choices) == 1) {
            plot_ly() %>% add_trace(data = gear3(), x = gear3()$mpg, y = gear3()$disp, type = "scatter", mode = "lines") %>% 
                add_trace(data = gear4(), x = gear4()$mpg, y = gear4()$wt, type = "scatter", mode = "lines") %>% 
                add_trace(data = gear5(), x = gear5()$mpg, y = gear5()$qsec, type = "scatter", mode = "lines")
        }
        
        
    })
}

shinyApp(ui = ui, server = server)

AND here is code for the plot that is successful at making the desired figure but it doesn't react to inputs selected or the amount of inputs selected.

E.g. this is the included picture of the graph with all three inputs selected.1 <- Desired output

 output$distPlot <- renderPlotly({
        fig1 <- plot_ly() %>% add_trace(data = gear3(), x = gear3()$mpg, y = gear3()$disp, type = "scatter", mode = "lines")
        fig2 <- plot_ly() %>% add_trace(data = gear4(), x = gear4()$mpg, y = gear4()$wt, type = "scatter", mode = "lines") 
        fig3 <- plot_ly() %>% add_trace(data = gear5(), x = gear5()$mpg, y = gear5()$qsec, type = "scatter", mode = "lines") 
        
        subplot(fig1, fig2, nrows = 2, shareX = TRUE)
        
        
    })



Aucun commentaire:

Enregistrer un commentaire