NewUser
NewUser

Reputation: 346

How to update datatable with formatStyle via dataTableProxy

I am trying to update the backgroundColor of a column using a dataTableProxy. However, I am not sure of how to properly handle the column names. Here's an example :

library(shiny)
library(DT)

ui <- fluidPage(
   fluidRow(
       DT::dataTableOutput("myplot")
    )
)

server <- function(input, output) {

    output$myplot <- DT::renderDataTable({
        datatable(as.data.frame(rnorm(5))) %>%
            formatStyle(1, backgroundColor = 'red')
    })

    proxy <- DT::dataTableProxy("myplot")
    mycolors <- c("red", "green", "blue")

    observe({
        invalidateLater(1000)

        proxy %>% replaceData(as.data.frame(rnorm(5)))

        # proxy %>% replaceData(as.data.frame(rnorm(5))) %>%
        #     formatStyle(1, backgroundColor = sample(mycolors, 1))
    })
}


shinyApp(ui = ui, server = server)

Even though the numbers update as I would expect, I can't get the formatStyle to work (commented out code). It keeps showing the following error :

Warning: Error in !: invalid argument type
  56: name2int

And here's the error I get using "rnorm(5)" as column when calling formatStyle.

Warning: Error in name2int: You specified the columns: rnorm(5), but the column names of the data are 
  57: stop

What is the correct way of referencing the columns when using the dataTableProxy ?

Upvotes: 5

Views: 2091

Answers (1)

ismirsehregal
ismirsehregal

Reputation: 33407

The problem here is not based on the column names. formatStyle doesn't take a proxy object as an argument, it expects a table object created by datatable().

See ?dataTableProxy for the functions available to manipulate existing datatable instances. Accordingly you cannot directly change the backgroundcolor via a dataTableProxy.

However, one of the functions available to deal with proxy objects is replaceData() which you are using above. Furthermore, formatStyle gives us the possibility to set the backgroundcolor based on the data available in the table.

Accordingly you can create a helper column (and dynamically change it) holding the information for your background color, hide it and tell formatStyle to change the color according to that coulmn.

Here is a working example:

library(shiny)
library(DT)

ui <- fluidPage(
  fluidRow(
    DT::dataTableOutput("myplot")
  )
)

server <- function(input, output) {
  
  mycolors <- c("red", "green", "blue")
  
  output$myplot <- DT::renderDataTable({
    DF <- data.frame(replicate(5, sample(rnorm(5), 10, rep = TRUE)), "background_color" = sample(mycolors, 1))
    HideCols <- which(names(DF) %in% c("background_color"))
    datatable(DF, options = list(columnDefs = list(list(visible=FALSE, targets=HideCols)))) %>% formatStyle(
      "background_color",
      target = "row",
      backgroundColor = styleEqual(levels = mycolors, values = mycolors)
    )
  })
  
  proxy <- DT::dataTableProxy("myplot")
  
  observe({
    invalidateLater(1000)
    DF <- data.frame(replicate(5, sample(rnorm(5), 10, rep = TRUE)), "background_color" = sample(mycolors, 1))
    proxy %>% replaceData(DF)
  })
}

shinyApp(ui = ui, server = server)

Result

For further information please see this.

Upvotes: 2

Related Questions