Search code examples
rflextablerhandsontable

R: How to fix table's column width using flextable() package?


I have two tables. First columns of both of them should have fixed width, say, 1,5 inches. Below there is a sample script where for the table named df1 I used flextable() function and for the table named df2 I used flextable() and width() function. However, desired columns' width is not getting fixed to the given length, i.e. 1,5 inches.

Can someone show me how to get column width fixed?

library(shinydashboard)
library(shiny)
library(rhandsontable)
library(flextable)

df1 = data.table(
    "Сolumn1"= as.character(),
    "Column2"= as.numeric(),
    "Сolumn3"= as.character()
)

flextable(
  df1,
  col_keys = names(df1),
  cwidth = 0.75,
  cheight = 0.25
)

qflextable(df1)

df2 = data.table(
    "Сolumn1"= as.character(),
    "Column2"= as.numeric(),
    "Сolumn3"= as.character()
)

df2 <- flextable(head(df2))
df2 <- width(df2, width = 1.5)

ui <- dashboardPage(
  dashboardHeader(title = "Assets"),
  dashboardSidebar(
    menuItem("Home", tabName = "home"),
    menuItem("Current assets",
      tabName = "CurrentAssets",
      menuSubItem("Inventory", tabName = "inventory")
      )
    ),
  dashboardBody(
    tabItems(
      tabItem(
        tabName = "inventory",
        column(
          width = 7,
          "df1",
          rHandsontableOutput("Table1")  
        ),
        column(
          width = 7,
          "df2",
          rHandsontableOutput("Table2")
        )
      )
    )
  )
)

server <- function(input, output, session) {
  output$Table1 <- renderRHandsontable({
     rhandsontable(df1, stretcH="all")
  })

  output$Table2 <- renderRHandsontable({
     rhandsontable(df2, stretcH="all")
  })
}

shinyApp(ui, server)

Solution

  • It's not clear to me what you are trying to achieve with flextable. As is your code returns an error as you are passing a flextable object to rhandsontable. You can only have one of both. Either do you create your tables using flextable or using rhandsontable. But it's not possible to first create a flextable with a fixed column width and then convert it magically to a rhandsontable. If you want the latter then you have to set the column width using the options provided by the rhandsontable package.

    From the docs on sizing a rhandsontable you could set the column widths using the colWidths= argument of hot_cols(). Additionally, rhandsontable() has an argument rowHeaderWidth to set the width of the row names column.

    Below I set the rowHeaderWidth to 200 and use a numeric vector to set width of the first column to 100 and to 50 for the second and third.

    Note: For a column layout you have only 12 columns in total, i.e. setting the column widths to 7 for both tables will not work when you want both tables in one row. Hence, I set the width to 6 for both.

    library(shinydashboard)
    library(shiny)
    library(rhandsontable)
    
    df1 <- data.frame(
      "Сolumn1" = as.character(),
      "Column2" = as.numeric(),
      "Сolumn3" = as.character()
    )
    
    df2 <- data.frame(
      "Сolumn1" = as.character(),
      "Column2" = as.numeric(),
      "Сolumn3" = as.character()
    )
    
    ui <- dashboardPage(
      dashboardHeader(title = "Assets"),
      dashboardSidebar(
        menuItem("Home", tabName = "home"),
        menuItem("Current assets",
          tabName = "CurrentAssets",
          menuSubItem("Inventory", tabName = "inventory")
        )
      ),
      dashboardBody(
        tabItems(
          tabItem(
            tabName = "inventory",
            column(
              width = 6,
              "df1",
              rHandsontableOutput("Table1")
            ),
            column(
              width = 6,
              "df2",
              rHandsontableOutput("Table2")
            )
          )
        )
      )
    )
    
    server <- function(input, output, session) {
      output$Table1 <- renderRHandsontable({
        rhandsontable(df1, stretch = "all", rowHeaderWidth = 200) |> 
          hot_cols(colWidths = c(100, 50, 50))
      })
    
      output$Table2 <- renderRHandsontable({
        rhandsontable(df2, stretch = "all", rowHeaderWidth = 200) |> 
          hot_cols(colWidths = c(100, 50, 50))
      })
    }
    
    shinyApp(ui, server)
    

    enter image description here