7

I have an application for real time data visualization build with R shiny library. I do periodic data reload from file using reactivePoll function. What I do not like about this is that whenever data reloads the whole application refreshes.

So for example if I have DT table output with selection and I use this selection input$table_rows_selected it resets to NULL whenever data reloads which is not user-friendly at all.

Is it overall possible to change data output without interrupting user?

UPDATE.

Can this be achieved with any other package for displaying tables - googleVis or other?

Working example.

library(shiny)
library(DT)

runApp(shinyApp(
  ui = fluidPage(dataTableOutput('table')),
  server = function(input, output, session) {
    pollData <- reactivePoll(4000, session,
                             checkFunc = function(){ Sys.time() },
                             valueFunc = function(){ data.frame(id = sample(letters[1:3]), a = runif(3), b = runif(3), c = runif(3)) })
    output$table <- renderDataTable({pollData()})
    proxy <- dataTableProxy('table')
    observeEvent(pollData(), {
      selectRows(proxy, input$table_rows_selected)
    })}
))

I have taken this example from @NicE answer and added id column. The point is that @NicE answer is OK if one needs certain row to be selected when that row is identified by the row number.

Now suppose I need a row to be selected when that row is identified by some id value. That is if I select a row with id equal b, then the next time data reloads I want the row to be selected with the same id value.

danas.zuokas
  • 4,551
  • 4
  • 29
  • 39
  • This is very common with `DT` package. You will need to build some custom `JS` to take care of that. Alternatively you can use xtable as the `blinking` isnt that noticeable. have a look here http://stackoverflow.com/questions/26976860/how-to-change-datatable-row-background-colour-based-on-the-condition-in-a-column – Pork Chop Mar 10 '16 at 08:19
  • Is the data reload just adding new lines or updating already existing values? You could use `dataTableProxy` to change the table without re-rendering it. If you just want the `table_rows_selected` to stay on your new table, you can also set them programatically after updating the data. – NicE Mar 14 '16 at 10:52
  • It can be a new table with few rows changed but most of the time it will be value updating. @NicE can you explain what do you mean by "set them programatically" part? – danas.zuokas Mar 15 '16 at 19:10
  • I would suggest doing something like the experience of editing your question on stackoverflow. A banner pops up that tells the user new data is available. User clicks the banner to manually update the data table. Of course this only works if your data update relatively infrequently. – Xiongbing Jin Mar 15 '16 at 19:47
  • Can you provide a working example? – K. Rohde Mar 16 '16 at 10:55
  • Added a working example. – danas.zuokas Mar 18 '16 at 09:52

1 Answers1

11

You could use a dataTableProxy to select rows when the datable is created after a pollData update. Here's an example, the dataframe is refreshed every 4 seconds:

library(shiny)
library(DT)

ui <- fluidPage(dataTableOutput("table"))

server <- function(input,output,session){
        values <- reactiveValues()
        pollData <- reactivePoll(4000, session,
                                 checkFunc=function(){
                                         Sys.time()
                                 },
                                 valueFunc=function(){                             
                                         data.frame(a=sample(c("a","b","c"),3),b=runif(3),c=runif(3),stringsAsFactors = F)
                                 })

        output$table <- renderDataTable({ pollData()})

        observe({
                values$selected <- pollData()$a[input$table_rows_selected]
        })

        proxy = dataTableProxy('table')
        observeEvent(pollData(),{
                selectRows(proxy, which(pollData()$a %in% values$selected))
        })
}

shinyApp(ui,server)

Update: on the above code, when the data changes, the selected rows are the ones that have the same first column as previously.

NicE
  • 21,165
  • 3
  • 51
  • 68
  • 3
    Just a note that this requires the development version of `DT`, as the `dataTableProxy` command is not available in the release version. You need `devtools::install_github('rstudio/DT')` – Xiongbing Jin Mar 16 '16 at 15:27
  • Thank you for your answer. Could you revise your answer based on my update of the question? The problem is that I need a row that is identified by some id value. – danas.zuokas Mar 18 '16 at 09:53
  • 1
    Just save the id value, something like save <- pollData()[idvar,input$table_rows_selected] and select them with which(pollData()[idvar,]==save) – Sebastian Mar 18 '16 at 10:00
  • @Sebastian can you be more specific, where should I put those lines of code? – danas.zuokas Mar 18 '16 at 11:21
  • I updated the code to do what you want, if the user selects a row with an "b" in column a of the sample data, this row will be selected when the data changes. – NicE Mar 18 '16 at 11:48