1

I've been working with this post as a starting point. Update handsontable by editing table and/or eventReactive

Very helpful, but I'm trying to extend it to specify the number of values in the table, then update a plot based on the table values after editing.

Here's what I have so far.

library(shiny)
library(rhandsontable)
library(colorSpec)

ui <- fluidPage(
  numericInput("x", "number of values", 2),
  rHandsontableOutput('table'),
  textOutput('result'),
  plotOutput('plot'),
  actionButton("recalc", "generate new random vals and calculate")
)


server <- function(input,output,session)({
  values <- reactiveValues(data=as.data.frame(runif(input$x)))

  observe({
    input$recalc
    values$data <- as.data.frame(runif(input$x))
  })

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


  output$table <- renderRHandsontable({
    rhandsontable(values$data)
  })


  output$result <- renderText({
    sum(values$data)
  })

  output$plot <- reactivePlot({
    barplot(values$data)
  })

})

shinyApp(ui = ui, server = server)

I get an error on the reactiveValues line because I'm trying to use input$x. The previous post had a hard coded value of 2.

agf1997
  • 2,668
  • 4
  • 21
  • 36

2 Answers2

2

I think you were almost there. You can, however, not use an input for creating a reactive value. But this is anyways not eneded and you can initiate it with a NULL.

library(shiny)
library(rhandsontable)

ui <- fluidPage(
  numericInput("x", "number of values", 2),
  rHandsontableOutput('table'),
  textOutput('result'),
  plotOutput('plot'),
  actionButton("recalc", "generate new random vals and calculate")
)


server <- function(input,output,session)({
  values <- reactiveValues(data = NULL) ## assign it with NULL

  ## button press resets now the data frame
  observeEvent(input$recalc, { 
    values$data$x <- 0
  })

  ## changes in numericInput sets all (!) new values
  observe({
    req(input$x)
    values$data <- data.frame(x = runif(input$x))
  })

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


  output$table <- renderRHandsontable({
    req(values$data)
    rhandsontable(values$data)
  })


  output$result <- renderText({
    req(values$data)
    sum(values$data)
  })

  output$plot <- renderPlot({
    req(values$data)
    barplot(values$data$x)
  })

})

shinyApp(ui = ui, server = server)
thothal
  • 16,690
  • 3
  • 36
  • 71
  • This is close ... is there a way to add the additional random value as the number in the `numericInput` is increased? My example actually doesn't perfectly match my real world situation. I would like to have the `actionbutton` set all values to `0` so I think separating the addition of the new value and calculation of the new sum from the button action is necessary. – agf1997 Oct 02 '18 at 15:30
  • 1
    Changed my code. but i am not sure what you want to achieve? I assume now that teh button, sets everything to `0` while changes in `numericInput` creates a set of new random variables – thothal Oct 02 '18 at 15:47
  • Sorry if I didn't explain clearly but you're example seems to be doing exactly what I was looking for!! Let me do a little more testing but this is clearly on the right track. – agf1997 Oct 02 '18 at 16:07
1

You can use reactive() instead of reactiveValues to do this:

library(shiny)
library(rhandsontable)
library(colorSpec)

ui <- fluidPage(
  numericInput("x", "number of values", 2),
  rHandsontableOutput('table'),
  textOutput('result')
)


server <- function(input,output,session)({

  values <- reactive({
    foo <- as.data.frame(runif(input$x))
    colnames(foo) <- c("Col1")
    return(foo)
  })

  output$table <- renderRHandsontable({
    rhandsontable(values())
  })


  output$result <- renderText({
    sum(values())
  })

})

shinyApp(ui = ui, server = server)
Vishesh Shrivastav
  • 2,079
  • 2
  • 16
  • 34