Inconsistent digits beyond decimal when combined with scientific notation kableExtra table R markdown

It would really help if you supplied a reproducible example, since I don't know what your un-formatted numbers are. However, adding some arbitrary extra precision for demonstration, how about something like this:

suppressPackageStartupMessages(library(tidyverse))

formatme <- tribble(
  ~estimate, ~P_value, 
   14.93423,  1.064325e-173, 
   -5.58189,  3.863223e-08 , 
   -4.00146,  0.01792431   , 
   -1.64129,  0.1321123    , 
   -5.32435,  1.282435e-06 , 
   -4.81021,  1.634358e-05 , 
   -0.97118,  0.373213     , 
   -2.12204,  0.051729     , 
   -1.88072,  0.1          , 
   -1.71032,  0.116
)

formatme %>% 
mutate(
  P_value = if_else(
    P_value < 0.01, 
    formatC(P_value, digits = 2, format = "e"), 
    formatC(P_value, digits = 2, format = "f", drop0trailing = FALSE)
  )
) %>% 
mutate_if(
  is.numeric, 
  function(x) {
    formatC(x, digits = 2, format = "f", drop0trailing = FALSE)
  }
)
#> # A tibble: 10 x 2
#>    estimate P_value  
#>    <chr>    <chr>    
#>  1 14.93    1.06e-173
#>  2 -5.58    3.86e-08 
#>  3 -4.00    0.02     
#>  4 -1.64    0.13     
#>  5 -5.32    1.28e-06 
#>  6 -4.81    1.63e-05 
#>  7 -0.97    0.37     
#>  8 -2.12    0.05     
#>  9 -1.88    0.10     
#> 10 -1.71    0.12

Notes

  • You'd want to choose your own threshold for the conditional application of formats to P_value — I just guessed at a reasonable value.
  • I simplified some of the formatC options, but since I don't know exactly what your actual data look like and what you want, you might need to add some back. However, since you're outputting as HTML (via kableExtra), setting width and left-adjustment (flag = "-") won't do much, because HTML ignores extra whitespace.
  • I left out the calls to kableExtra::cell_spec because your problem is with formatC, and I wanted to make the above reprex output clearer. Here's what the example looks like with the kableExtra bits:
formatme %>% 
  mutate(
    P_value = cell_spec(
      if_else(
        P_value < 1e-02, 
        formatC(P_value, digits = 2, format = "e"),
        formatC(P_value, digits = 2, format = "f")
      ),
      format = "html",
      color = ifelse(P_value <= 0.05, yes = "red", no = "blue"),
      escape = F
    )
  ) %>%
  mutate_if(
    is.numeric, 
    function(x) {
      cell_spec(
        formatC(x, digits = 2, format = "f", drop0trailing = FALSE),
        format = "html"
      )
    }
  )
3 Likes