Reputation: 390
I have just learnt KableExtra and know to how to use conditionally formating the entire column using mutate() as explained in the doc using mutate such as:
mutate(
mpg = cell_spec(mpg, background = ifelse(mpg > 20, "red", "blue"))
)
But what I don't know is, how to change background colours of only certain rows in each column whilst all rows are being displayed.
For example, my data:
df <- data.frame( region1 = c("A", sample(1:5,3)),
region2 = c("B", sample(1:5,3)),
region3 = c("C", sample(1:5,3)),
region4 = c("A", sample(1:5,3)) )
Now I want to format only second and third row. I dont want to change the color background of first and last row. These second and third row should be 'red' when above 1, or yellow when equal to 1 or green when below 1.
Some one could help me this?
Upvotes: 5
Views: 8294
Reputation: 12084
Here's an example that ignores the first and last rows and colours according to value, like you say, but ignores letters.
First, I load the libraries.
# Load libraries
library(knitr)
library(kableExtra)
Next, I create a dummy data frame.
# Create data frame
df <- data.frame( region1 = c(sample(c(-5:5, letters[1:5]), 10, replace = TRUE)),
region2 = c(sample(c(-5:5, letters[1:5]), 10, replace = TRUE)),
region3 = c(sample(c(-5:5, letters[1:5]), 10, replace = TRUE)),
region4 = c(sample(c(-5:5, letters[1:5]), 10, replace = TRUE)), stringsAsFactors = FALSE )
Here, I define the function for formatting cells. I ignore the first and last rows and check if the character is a letter or number, then colour accordingly.
foo <- function(x, n, nmax){
cell_spec(x, background = ifelse(is.na(as.numeric(x)), "white",
ifelse(n == nmax | n == 1, "white",
ifelse(x > 1, "red",
ifelse(x < 1, "green", "yellow")))))
}
Finally, I apply the function.
df %>%
mutate_all(funs(foo(., n = row_number(), nmax = n()))) %>%
kable(escape = FALSE) %>%
kable_styling()
Upvotes: 4
Reputation: 44997
That's not a good design for a dataframe: columns need to be all one type, so your numbers will be coerced to character.
Nevertheless, you can do what you ask for as follows.
fixcol <- function(col) {
x <- as.numeric(col[2:3])
x <- cell_spec(x, background = ifelse(x > 1, "red", ifelse(x == 1, "yellow", "green")))
col[2:3] <- x
col
}
df <- as.data.frame(lapply(df, fixcol))
kable(df, escape = FALSE)
Upvotes: 0