Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I build a reactive dataframe in R / Shiny?

Tags:

dataframe

r

shiny

I want to use a reactive dataframe to show multiple plots and graphs. I have a dataset that I would like to be able to filter on. Ones I have found the right filter settings, I would like to show the data on a number of different plots – that will update, if the filter settings are changed.

This might explain, what I’m trying to do:

UI:

fluidPage(
  sidebarLayout(
    sidebarPanel(

      checkboxGroupInput("checkGroups", 
                         label = "Include", choices = list("1 star" = 1, "2 star" = 2,
                                                           "3 star" = 3, "4 star" = 4,
                                                           "5 star" = 5),
                         selected = list(1, 2, 3, 4, 5)),

      checkboxInput("checkbox", "Include Replies"),

      actionButton("Button", "Update")

    ),
    mainPanel(

      showOutput("plot", "nvd3"),

      showOutput("pieplot", "nvd3")

    )
  )
)

SERVER:

rating <- c(2, 3, 5, 4, 1, 5, 3, 1, 4)
date_time <- c("2015-05-14", "2015-05-07", "2015-05-06", "2015-04-11", "2015-01-07", "2014-12-06", "2014-04-11", "2014-01-07", "2013-12-06")
repliesOnly <- c(TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE)
data <- data.frame(rating, date_time, repliesOnly)

function(input, output, session) {

  load("data.Rdata")

  newdata <- reactive({

    filter_data <- data

    filter_data <- filter_data %>% filter(rating %in% input$checkGroups)

    filter_data <- filter_data %>% filter(repliesOnly %in% input$checkbox)

    return(filter_data)

  })

  output$plot <- renderChart({

    plot <- nPlot(rating ~ date_time, data = newdata, 
                  type = "multiBarHorizontalChart", dom = 'plot')
    return(plot)

  })

  output$pieplot <- renderChart({

    pieplot <- nPlot(rating ~ date_time, data = newdata, 
                  type = "pieChart", dom = 'pieplot')
    return(pieplot)

  })

}

Can it be done? Of course I can just include the filter for each graph-output, but my dataset is rather big and my filter is quite complex, so if it should calculate it for each graph it takes forever.

All help is deeply appreciated!

like image 807
Emil Lykke Jensen Avatar asked May 25 '15 17:05

Emil Lykke Jensen


People also ask

What are reactive values in R shiny?

Reactive values contain values (not surprisingly), which can be read by other reactive objects. The input object is a ReactiveValues object, which looks something like a list, and it contains many individual reactive values. The values in input are set by input from the web browser.

What does the renderPlot function do in shiny?

renderPlot is an reactive function that can take input data from the ui. R script and feed it into the server. R script. It then actively updates the information within its function.

What is reactive function?

Reactive functions are functions that can read reactive values and call other reactive functions. Whenever a reactive value changes, any reactive functions that depended on it are marked as "invalidated" and will automatically re-execute if necessary.


2 Answers

Thank you for this example; I also need a reactive dataframe filtering. After fighting 2 hours with the following error:

cannot coerce class ""reactive"" to a data.frame

your post helped me solve the problem. I dare post a simplified version of your example, easier to reproduce (no showOutput or readChart calls), for future reference to other shiny users.

N.B.: I use the single-file application.

library(shiny)

rating <- c(2, 3, 5, 4, 1, 5, 3, 1, 4)
date_time <- c("2015-05-14", "2015-05-07", "2015-05-06", "2015-04-11",
"2015-01-07", "2014-12-06", "2014-04-11", "2014-01-07", "2013-12-06")
repliesOnly <- c(TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE)
data <- data.frame(rating, date_time, repliesOnly)
data$rating <- as.character(data$rating)

ui <- fluidPage(
   sidebarLayout(
   sidebarPanel(

   checkboxGroupInput("checkGroups", 
                     label = "Include", choices = c("1 star" = 1, 
                                                       "2 star" = 2,
                                                       "3 star" = 3, 
                                                       "4 star" = 4,
                                                       "5 star" = 5),
                     selected = list(1, 2, 3, 4, 5))
),

mainPanel(
  tableOutput("view")
    )
   )
    )

server <- function(input, output, session) {
  newData <- reactive({
         data <- subset(data, rating %in% input$checkGroups)
 })

output$view <- renderTable({ newData() })

}

shinyApp(ui = ui, server = server)
like image 94
user7580792 Avatar answered Sep 20 '22 16:09

user7580792


Thanks for the help - this worked:

SERVER:

library(shiny)
library(rCharts)

rating <- c(2, 3, 5, 4, 1, 5, 3, 1, 4)
date_time <- c("2015-05-14", "2015-05-07", "2015-05-06", "2015-04-11", "2015-01-07", "2014-12-06", "2014-04-11", "2014-01-07", "2013-12-06")
repliesOnly <- c(TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE)
data <- data.frame(rating, date_time, repliesOnly)
data$rating <- as.character(data$rating)


function(input, output, session) {

  load("data.Rdata")

  datadata <- data
  makeReactiveBinding("datadata")

  newData <- reactive({

    input$Button
    isolate({

      datadata <- data

      datadata <- subset(datadata, rating %in% input$checkGroups)


    })

  })

  output$plot <- renderChart({

    datadata <- newData()

    plot <- nPlot(rating ~ date_time, data = datadata, 
                  type = "multiBarHorizontalChart", dom = 'plot')
    return(plot)

  })

  output$pieplot <- renderChart({

    datadata <- newData()

    pieplot <- nPlot(rating ~ date_time, data = datadata, 
                  type = "pieChart", dom = 'pieplot')
    return(pieplot)

  })

}
like image 21
Emil Lykke Jensen Avatar answered Sep 18 '22 16:09

Emil Lykke Jensen