1

I have an app with two tables. One table is a renderhandsontable object and the other is just a rendertable object. I would like for when I update my renderhandsontable object for it to automatically update my rendertable object. My renderhandontable object is created by data elsewhere in the app using a number of filters.

I have referenced several very useful posts here to help me get this far in creating a reactive table that could be used in multiple output objects such as

How to render multiple output from the same analysis without executing it multiple time? (Shiny)

Get selected rows of Rhandsontable

Handsontable : how to change cell value in render function

but I cannot seem to get past this last hurdle. I also tried adding a button (using eventReactive) so the table would update when I pressed it rather than automatically, but had no luck there (and automatic would definitely be preferred).

I have created an overly simplified version of my server code below.

#dummy data
x = c('A','A','A', 'B','B', 'c')
y = c('G1', 'G1', 'G1', 'G2', 'G2','G3')
z = c('100', '200', '300', '400','500','600')

b=data.frame('Category' = x,
             'Group' = y,
             'Total' = z)

#create reactive object to be used in multiple places
test <- reactive({

  t <-filter(b, b$Category %in% input$cat & b$Group %in% input$group)

  return(t)

})

output$test_table <- renderTable({

  tbl = data.frame(matrix(0, ncol = 4, nrow = 4))

#I know something needs to be done prior to this step to get updated values #of test()

  tbl[1,1] <- test()[1,3]

  return(tbl)
})


output$contents <- renderRHandsontable({

  rhandsontable(test())

})

I can get my tables to appear properly and the data to update initially, but once I make an update to my table, it is not reflected in my second table.

I have really been struggling with this for quite some time so any help or hints would be greatly appreciated !

CJJ
  • 75
  • 9

1 Answers1

1

Please read this. You can access the rhandsontable params via input$my_id. To get the current data use input$my_id$params$data.

Here is what I think you are after:

library(shiny)
library(rhandsontable)

ui <- fluidPage(rHandsontableOutput("contents"),
                tableOutput("test_table"),
                tableOutput("test_table_subset"))

server <- function(input, output) {

  # dummy data
  x = c('A', 'A', 'A', 'B', 'B', 'C')
  y = c('G1', 'G1', 'G1', 'G2', 'G2', 'G3')
  z = c('100', '200', '300', '400', '500', '600')

  b = data.frame('Category' = x,
                 'Group' = y,
                 'Total' = z)

  # create reactive object to be used in multiple places
  test <- reactive({
    t <- b # dplyr::filter(b, b$Category %in% input$cat & b$Group %in% input$group)
    return(t)
  })

  output$contents <- renderRHandsontable({
    rhandsontable(test())
  })

  contentsTableDat <- reactive({
    req(input$contents)
    hot_to_r(input$contents)
  })

  output$test_table <- renderTable({
    contentsTableDat()
  })

  output$test_table_subset <- renderTable({
    contentsTableDat()[1, 3]
  })
}

shinyApp(ui = ui, server = server)
ismirsehregal
  • 30,045
  • 5
  • 31
  • 78
  • Thank you @ismirsehregal ! I knew I had to use "$" but I could not totally follow all of the examples and could not find solid documentation somewhere. I am currently getting an error: "Warning: Error in <-: invalid subscript type 'list'". I will continue to play around with it and see if this helps though ! – CJJ May 14 '19 at 11:58
  • @CjV That is because you didn't provide `input$cat` and `input$group` for your `filter` call. Please see my edit. – ismirsehregal May 14 '19 at 12:26
  • That makes sense thank you @ismirsehregal ! One more question, how would I access just an element of the reactive table ? For example, if I wanted to just use the value in the 1st row, 3rd column to update the table (my data will change from this simplified format-it will likely end up using a whole column and multiplying data in the other table by that column), it does not appear that I can do input$contents$params$data[1,3] ? Does my question make sense? Is there a way to treat is as a data frame? – CJJ May 14 '19 at 13:51
  • You are receiving a `list()` you can access it like: `input$contents$params$data[[1]][3]` or take the data.frame I prepared: `contentsTableDat[1, 3]` – ismirsehregal May 14 '19 at 14:18
  • 1
    This has been really helpful ! Thank you so much for the explanations ! – CJJ May 14 '19 at 14:22
  • Revisiting this: This code worked perfectly for me ! The new issue I am having now (my data is no longer that format) is using "gather" with the reactive output. When I do `data <- gather(contentsTableDat(),key = Date,value = col4,-c(col1,col2,col3))` I get the error `Error in UseMethod: no applicable method for 'gather_' applied to an object of class "c('matrix', 'list')"`. I have tried a number of different ways on indexing the table to treat it as a data frame but have had no luck. I am having difficulty changing the column names as well.Do you know why I may be getting this error? – CJJ Jun 03 '19 at 21:41
  • Just updated my answer using `hot_to_r` you might want to try it. But actually I think it might be better if you post another question illustrating the new problem. – ismirsehregal Jun 04 '19 at 07:08