rshinydtright-align

R+Shiny+DT: automatically right align numeric columns


Please have a look at the reprex at the end of this post. I have a tibble with mix of numerical and non-numerical columns. The numerical values are all rounded up to two decimals. I use formatStyle and I manually select the numerical columns which I want to be right aligned.

Unfortunately, in the real-life shiny app I do not know each time how many numerical columns I will have, so I need a way to select them automatically in order to align them.

It must be a one-liner, but so far I have been unsuccessful. Anyone can help me here? Many thanks!

library(shiny)
library(tidyverse)
library(DT)
#> 
#> Attaching package: 'DT'
#> The following objects are masked from 'package:shiny':
#> 
#>     dataTableOutput, renderDataTable



round_all <-  function(df, n){


res <- df %>% mutate(across(where(is.numeric), ~round(.x,n) ))

    
return(res)

}


set.seed(1234)

df <- tibble(x=letters[1:5], y=LETTERS[10:14],
             w=rnorm(5), z=rnorm(5)) %>%
    round_all(2)


ui <- fluidPage(

mainPanel(DTOutput("table"))
    
)


server <- function(input, output) {

    output$table <- renderDT({datatable(df)} %>%
                             formatStyle(columns=c("w", "z"),
                                         textAlign = 'right')
              )


}





shinyApp(ui = ui, server = server)
#> 
#> Listening on http://127.0.0.1:7374

Created on 2021-09-21 by the reprex package (v2.0.1)


Solution

  • You can write e.g. numeric_cols <- df %>% keep(is.numeric) %>% colnames():

    library(shiny)
    library(tidyverse)
    library(DT)
    
    round_all <- function(df, n) {
      res <- df %>% mutate(across(where(is.numeric), ~ round(.x, n)))
    
      return(res)
    }
    
    
    set.seed(1234)
    
    df <- tibble(
      x = letters[1:5], y = LETTERS[10:14],
      w = rnorm(5), z = rnorm(5)
    ) %>%
      mutate_if(is.numeric, ~ .x %>% round(2))
    
    ui <- fluidPage(
      mainPanel(DTOutput("table"))
    )
    
    
    server <- function(input, output) {
      numeric_cols <- df %>% keep(is.numeric) %>% colnames()
      
      output$table <- renderDT({
        datatable(df)
      } %>%
        formatStyle(
          columns = numeric_cols,
          textAlign = "right"
        ))
    }
    
    shinyApp(ui = ui, server = server)