rshinyr-dygraphs

How do I send multiple dySeries to a secondary axis based on checkbox input in shiny?


I'm trying to plot a dyGraph using the lungDeaths timeseries, but I want "mdeaths" and "fdeaths" to be on the secondary axis, if at least one of them is selected alongside "ldeaths".

Here's a working example:

global.R

library(dygraphs)
library(shiny)
library(datasets)
library(stringr)

lungDeaths <- cbind(mdeaths, fdeaths)

ui.R

shinyUI(fluidPage(

titlePanel("Predicted Deaths from Lung Disease (UK)"),

sidebarLayout(
    sidebarPanel(

        id="sidebar", width = 3,
        div(
            checkboxGroupInput(
                inputId = "selection", label = "Variables:",
                choiceNames = list("ldeaths",
                                   strong("mdeaths"),
                                   strong("fdeaths")
                                   ),
                choiceValues = c("ldeaths",
                                 "mdeaths",
                                 "fdeaths"), selected = "ldeaths"),
            uiOutput("rendered"),
            style = "font-size:75%"
        )

    ),
    mainPanel(
        dygraphOutput("dygraph")
    )
)
))

server.R

shinyServer(function(input, output) {

lungDeaths <- cbind(mdeaths, fdeaths, ldeaths)

rData <- reactive({
    rData <- ts(lungDeaths[,input$selection])
})

output$dygraph <- renderDygraph({

    if(length(input$selection) > 1 & length(str_subset(input$selection, 'ldeaths$'))>0){

        if(length(str_subset(input$selection, 'fdeaths$'))>0 & length(str_subset(input$selection, 'mdeaths$'))>0){
            dygraph(rData(), main = "Deaths from Lung Disease (UK)") %>% 
                dySeries("mdeaths", axis = 'y2') %>% 
                dySeries("fdeaths", axis = 'y2')
        }

        else if(length(str_subset(input$selection, 'mdeaths$'))>0){
            dygraph(rData(), main = "Deaths from Lung Disease (UK)") %>% 
            dySeries("mdeaths", axis = 'y2') 
        }
        else if(length(str_subset(input$selection, 'fdeaths$'))>0){
            dygraph(rData(), main = "Deaths from Lung Disease (UK)") %>% 
            dySeries("fdeaths", axis = 'y2')

        }
    }
    else
        dygraph(rData(), main = "Deaths from Lung Disease (UK)")
})
})

This code does what I want it to do, but I wanted to avoid using so many if's and else's, because the project I'm actually working with has 6 items that should go to y2 when selected. Is there any way to do it without having to specify each possibility?

I've already researched on how to add dySeries based on input and how to do conditional evaluation when using pipes, but the answers I found so far don't work for me. I usually get an error that says:

$ operator is invalid for atomic vectors


Solution

  • I made it, so I'm posting the answer to help anyone who's been struggling with the same issue...

    I was not using the if else correctly when trying to do the conditional pipe evaluation, that's why I kept receiving the error mentioned in the question.

    It turns out that I had to use the dot (.) to specify exactly where the object before the pipe was supposed to be inserted in the following function, probably because the function was inside a conditional evaluation. The code bellow does exactly what I wanted it to do:

     output$dygraph <- renderDygraph({
    
            dygraph(rData(), main = "Deaths from Lung Disease (UK)") %>% 
                {
                    if(length(str_subset(input$selection, 'mdeaths$')) > 0 )
                        dySeries(.,"mdeaths", axis = 'y2')
                    else
                        .
                } %>% 
                {
                    if(length(str_subset(input$selection, 'fdeaths$')) > 0 )
                        dySeries(.,"fdeaths", axis = 'y2')
                    else
                        .
                }
    
    })
    

    The dygraph now shows the dyseries on the secondary axis, whenever they are selected as inputs