2

My shiny code has an rhandstontable that the user can edit. This leads to an update of the rightmost columns, based on a custom function. the code also plots values from the table on two ggplots, which also get updated when the table values change. All of this works except that there is a funny double refresh that makes Shiny slow; my table isn't big, about 50rows by 23 columns where only 4 columns are used in the plots but about 12 columns go into my custom function.

Is there a way to make shiny faster using observe(), reactiveValues, or other related functions?

I'm new at reactive expressions and I've been reading that it might be possible to make the app faster by caching data properly.

library(shiny)
library(rhandsontable)
library(tidyverse)
library(ggthemes)
library(ggrepel)

## Create the dataset
DF <- readRDS("data/DF2.Rds")
numberofrows <- nrow(DF)
# weighting variables
w1 = (c(4,3,1))
w2 = (c(1,1,1,1))
w3 = (c(2,2,1,2,1,1,2))
# Function to calculate scores
ScoresTbl <- function(data, w1, w2, w3){
  Description <- data[,1:9]
  Potential <- crossprod(t(data[,10:12]), w1)/sum(w1)
  Setting <- crossprod(t(data[,13:16]), w2)/sum(w2)
  Risk <- crossprod(t(data[,17:23]),w3)/sum(w3)
  data.frame(data[1:23],Potential,Setting,Risk) %>%
    mutate(
      SOP = rowMeans(data.frame(Potential,Setting,Risk)))
}

ui = fluidPage(
  fluidRow(column(12,
                  rHandsontableOutput('hotable1', width = "100%", height = "25%")#,
                  # actionButton("go", "Plot Update")
  )),
  fluidRow(column(6, plotOutput("plot1")),
           column(6, plotOutput("plot2")))
)
server <- shinyServer(function(input, output) {

  indat <- reactiveValues(data=ScoresTbl(DF,w1, w2, w3))

  observe({
    if(!is.null(input$hotable1))
      indat$data <- hot_to_r(input$hotable1)
  })


  output$hotable1 <- renderRHandsontable({
    rhandsontable(ScoresTbl(indat$data,w1, w2, w3))
  })

  output$plot1 <- renderPlot({
    ggplot(data = indat$data,
           aes(x=Potential,
               y=Setting, label = Project)) +
      geom_point(alpha = 0.5) +
      scale_size(range = c(2,15)) +
      geom_text_repel(colour = "black",size = 2.5) +
      theme_minimal()
  })
  output$plot2 <- renderPlot({
    ggplot(data = indat$data,
           aes(x=Potential,
               y=Setting, label = Project)) +
      geom_point(alpha = 0.5) +
      scale_size(range = c(2,15)) +
      geom_text_repel(colour = "black",size = 2.5) +
      theme_minimal()
  })
})

shinyApp(ui, server)
val
  • 1,629
  • 1
  • 30
  • 56

0 Answers0