Reputation: 305
I use the kableExtra()-package for conditional formatting of tables in an PDF-output Rmarkdown report. All works pretty much fine, but fails if in one column is a NA present.
The original report contains columns with percentage agreement on a specific variable (e.g. 21% (but % not in the cell)) , however it will show NA if the value is based on less than 10 answers for protection of subjects answers, therefore I will have potential NAs in the table.
Here is a small reprex for a case when it works (no NA):
---
output: pdf_document
---
```{r setup}
knitr::opts_chunk$set(echo = TRUE)
# load packages
library(tidyverse)
library(kableExtra)
# example when no NA are resent
df1 <- mtcars %>% select(mpg, cyl, disp)
df1 <- head(df1, 10)
# kable
df1 %>%
mutate(cyl = cell_spec(cyl, color = if_else(cyl == 8, "teal",
if_else(cyl == 6, "orange",
if_else(is.na(cyl), "black", "red"))))) %>%
kable("latex", escape = F, booktabs = TRUE, linesep = "")
```
here is the other one, when NAs are present:
```{r, eval=T}
# example when NA is present
df2 <- mtcars %>% select(mpg, cyl, disp)
df2 <- head(df2, 10)
df2$cyl[df2$cyl == 4] <- NA
# kable
df2 %>%
mutate(cyl = cell_spec(cyl, color = if_else(cyl == 8, "teal",
if_else(cyl == 6, "orange", "red")))) %>%
kable("latex", escape = F, booktabs = TRUE, linesep = "")
```
the error running the chunk is :
Error in if (substr(color, 1, 1) != "#") { : missing value where
TRUE/FALSE needed
the error when knitting is:
I also tried adding a third if_else() which evaluates to is.na() - the errors stay the same:
# kable
df2 %>%
mutate(cyl = cell_spec(cyl, color = if_else(cyl == 8, "teal",
if_else(cyl == 6, "orange",
if_else(is.na(cyl), "black","red"))))) %>%
kable("latex", escape = F, booktabs = TRUE, linesep = "")
My session.info:
R version 3.5.2 (2018-12-20)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Mojave 10.14.2
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] naniar_0.4.1 shurp2018_0.0.9000 kableExtra_1.0.1 forcats_0.3.0 stringr_1.3.1 dplyr_0.8.0 purrr_0.3.0
[8] readr_1.3.1 tidyr_0.8.2 tibble_2.0.99.9000 ggplot2_3.1.0 tidyverse_1.2.1
Upvotes: 0
Views: 1476
Reputation: 12420
It seems that you have two problems:
First, I think that by default, no color value is set. Yet it is also not overwritten when for some cells color = NA
. So you could solve it by setting color = NULL
(any other color would be concatenated with the ones assigned in the next step, which causes trouble).So this works somewhat for me:
```{r}
# kable
df2 %>%
mutate(cyl = cell_spec(cyl, color = NULL)) %>%
mutate(cyl = cell_spec(cyl, color = if_else(cyl == 8, "teal",
if_else(cyl == 6, "orange", "red")))) %>%
kable("latex", escape = F, booktabs = TRUE, linesep = "")
```
The problem is that the color of NA
is red now instead of black.
The second problem is that your ifelse
evaluations do not work correctly
You can also check what happens in your ifelse
function separately to get a better understanding of this problem:
> with(df2, if_else(cyl == 8, "teal",
+ if_else(cyl == 6, "orange",
+ if_else(is.na(cyl), "black","red"))))
[1] "orange" "orange" NA "orange" "teal" "orange" "teal" NA NA "orange"
But you can make it work by evaluating is.na(cyl)
first instead of last:
df2 %>%
mutate(cyl = cell_spec(cyl, color = if_else(is.na(cyl), "black",
if_else(cyl == 8, "teal",
if_else(cyl == 6, "orange", "red"))))) %>%
kable("latex", escape = F, booktabs = TRUE, linesep = "")
Upvotes: 2