AK.
AK.

Reputation: 3

R shiny: how to link slider and radio buttons to ggplot

I am very new to shiny and have read other similar posts without success, including: R shiny plots based on radio buttons and slider input

I am wanting to plot health outcome (selected from radio buttons) v out-of-pocket costs (OOP), with the year based on the slider

This is my code so far, plots not showing

ui:

 library(shiny)
 library(ggplot2)

 data <- read.csv("data.csv", header=TRUE)
 data

 data$OOP <- as.numeric(data$OOP)
 data$OOP

  shinyUI(fluidPage(
    titlePanel(title=h3("Out of pocket expenditure on health")),

    mainPanel(
      h5(textOutput("subheading")),
      plotOutput("view")),

    fluidRow(
        column(5,
           radioButtons("outcome", label=h4("Select Health Outcomes"),
                    choices=list("Mortality rate (per 100,000)", "Premature death risk (age 30-70)"), selected="Mortality rate (per 100,000)"),

           checkboxInput("smooth", "Add trend line")
),
        column(5,
            sliderInput("years", label=h4("Year"),
                   min=min(data$Year), max=max(data$Year), value=(min(data$Year)), step=5, sep="", animate=TRUE)
)
 )
   ))

server:

library(dplyr)
library(ggplot2)

shinyServer(
    function(input, output){
    formulaText <- reactive({
        paste("Health outcome:",input$outcome)
            })
        output$subheading <- renderText({formulaText()})

     datareact <- reactive({
        data %>%
        filter(Year == input$years) %>%
        select(Country, OOP, Mortality, Probability)
            })

     output$view <- renderPlot({
        p <- ggplot(datareact(), aes(x=OOP, y=input$outcome))+
           geom_point(aes(fill=Country))

        if(input$smooth)
           p <- p + geom_smooth()  
           })
         })

There is probably something wrong with the 'reactive' and 'renderPlot' lines. Any help is greatly appreciated, thanks

*Edit: This is what my data (snippet) looks like:

      Country Year     OOP Mortality Probability
1 Afghanistan 2000 No data     934.3        34.2
2 Afghanistan 2005      79     947.7        33.6
3 Afghanistan 2010      79     919.6        32.2
4 Afghanistan 2015    78.4     898.0        31.0
5     Albania 2000    64.6     710.3        20.0
6     Albania 2005    52.5     688.9        19.7

Upvotes: 0

Views: 1355

Answers (1)

A. Suliman
A. Suliman

Reputation: 13135

As always post reproducible data with dput and expected output is helpful. However, here is my solution let me know if update required.

library(shiny)
library(ggplot2)
library(dplyr)

#No data changed to NA
Input = ("Country Year     OOP Mortality Probability
   1 Afghanistan 2000 NA     934.3        34.2
   2 Afghanistan 2005      79     947.7        33.6
   3 Afghanistan 2010      79     919.6        32.2
   4 Afghanistan 2015    78.4     898.0        31.0
   5     Albania 2000    64.6     710.3        20.0
   6     Albania 2005    52.5     688.9        19.7")

data = read.table(textConnection(Input),header=TRUE)


ui <- shinyUI(fluidPage(
          titlePanel(title=h3("Out of pocket expenditure on health")),

      mainPanel(
        h5(textOutput("subheading")),
        plotOutput("view")),

     fluidRow(
        column(5,
               radioButtons("outcome", label=h4("Select Health Outcomes"),
                    choices=c("Mortality rate", "Premature death risk (age 30-70)"), selected="Mortality rate"),

             checkboxInput("smooth", "Add trend line")
       ),
         column(5,
               sliderInput("years", label=h4("Year"),
                   min=min(data$Year), max=max(data$Year), value=(min(data$Year)), step=1, sep="", animate=TRUE)
       )
     )
 ))


server <- shinyServer(function(input, output, session){
formulaText <- reactive({
  paste("Health outcome:",input$outcome)
})
output$subheading <- renderText({formulaText()})

datareact <- reactive({
  print(input$years)      #to check variable before passing 
  print(input$outcome)
  data <- data %>%
  #change input$outcome from renderPlot to reactive
  filter(Year >= input$years)

if (input$outcome == "Mortality rate") {data$outcome <- data$Mortality} else {
  data$outcome <- data$Probability    #Please note this is not the best solution for large data set 
  }
data
})

observe(print(datareact()))   #to check which data you get

output$view <- renderPlot({

  p <- ggplot(datareact(), aes(x=OOP, y=outcome, color=Country))+
    geom_point()

  if(input$smooth)
    p <- p + geom_smooth()

       p   #Enforce renderPlot to return p 
     })
  })

 shinyApp(ui,server)

Upvotes: 1

Related Questions