Search code examples
rconditional-formattingkableextratrailing

Why does kableExtra cell_spec lose trailing decimal zeros during conditional formatting?


I like to have two decimals, which works usually fine with kable. But using kableExtra for conditional formatting doesn't show trailing zeros if there is one cell, for which the condition is TRUE.

The MWE shows a situation where I get one bold cell if the value is greater than 1.2 and a situation with no bold cell as no value is greater than 1.5. The conditional formatting is working as expected. But in 3 of the 4 examples I lose the trailing zeros.

Any ideas why (and how to prevent the effect) are very welcome.

# MWE kableExtra cell_spec loses trailing decimal zeros during conditional formatting

rm(list=ls())
library("knitr")
library("kableExtra") 
library("dplyr")


df <- data.frame(item=c(1 , 1.2, 1.23))

# Condition for cell-specification for each cell false
df[df$item>1.5,1] <- cell_spec (df[df$item>1.5,1], "html",bold=TRUE)

# output for each cell with two decimals
knitr::kable(df, digits=2,  escape=FALSE)

item

1.00

1.20

1.23

df <- data.frame(item=c(1 , 1.2, 1.23))
# Condition for cell-specification for one cell true
df[df$item>1.2,1] <- cell_spec (df[df$item>1.2,1], "html",bold=TRUE)

# output for each cell with needed decimals only, trailing zeros lost
knitr::kable(df, digits=2, escape=FALSE)

item

1

1.2

1.23

df <- data.frame(item=c(1 , 1.2, 1.23))
# alternative way loses trailing zeros whether condition is TRUE or FALSE 
df %>%
  transmute(cell_spec(df$item, bold=ifelse(df$item>1.5,"TRUE","FALSE"))) %>%
  kable( digits=2, escape=FALSE)

cell_spec(dfitem,bold=ifelse(dfitem > 1.5, “TRUE”, “FALSE”))

1

1.2

1.23

df <- data.frame(item=c(1 , 1.2, 1.23))
df %>%
  transmute(cell_spec(df$item, bold=ifelse(df$item>1.2,"TRUE","FALSE"))) %>%
  kable( digits=2, escape=FALSE)

cell_spec(dfitem,bold=ifelse(dfitem > 1.5, “TRUE”, “FALSE”))

1

1.2

1.23


Solution

  • The effect arises because after cell_spec item is converted to character. Creating another column and converting into character with trailing zero before cell_spec does the trick.

    Nevertheless the condition for cell_spec follows the original values.

    df <- data.frame(item=c(1 , 1.2, 1.23))
    
    
    df$itemCharacter <- as.character(formatC(df$item, digits = 2, format = 'f')) #new character variable with format specification
    
    df[df$item>1.2,2] <- cell_spec (df[df$item>1.2,2], "html",bold=TRUE) #condition for cell_spec with the old variable, but assigned to the new variable
    
    knitr::kable(df$itemCharacter, digits=2,  escape=FALSE) #output of the new variable
    

    x

    1.00

    1.20

    1.23