首页 > 解决方案 > 基于每行不同的值范围的表格中单元格的条件样式 (R)

问题描述

我想创建一些表,其中来自多列的值根据每行不同的范围(并在“min”和“max”列中指定)获得条件样式。例如,我创建了以下内容:

a <- c('A', 'B', 'C', 'D', 'E')
b <- c(20, 25, 40, 55, 60)
c <- c(60, 30, 80, 50, 60)
min <- c(15, 20, 40, 55, 55)
max <- c(25, 30, 50, 65, 65)

df <- data.frame(a, b, c, min, max)

a  b  c min max
A 20 60  15  25
B 25 30  20  30
C 40 80  40  50
D 55 50  55  65
E 60 60  55  65

table.df <- df[,1:3]%>%
      select(a, everything())%>%
      kable("html", escape = F) %>%
      kable_styling(bootstrap_options = "striped", full_width = F, position = "left")

这给了我一个表格,其中没有显示 min 和 max 的列(如我所愿)。但我想添加一个条件语句,其中“b”和“c”列中超出“min”和“max”列定义的范围的值变为红色(或者这些单元格的背景)。不太熟悉样式表,所以任何帮助将不胜感激!

标签: rhtml-tablestylingkable

解决方案


包 tableHTML 为表格样式提供了很多选项,特别是如果您对 html 代码使用一些技巧,例如解决您的问题的一种方法如下:

基于此处的答案Highlight Predefined Words in Shiny DT table [Not through Search Highlight]

您修改满足条件的数据以包含文本格式(或任何其他 html 格式、字体颜色、背景颜色......),然后将其传递给tableHTML()withescape=FALSE

library(tableHTML)
library(dplyr)

a <- c('A', 'B', 'C', 'D', 'E')
b <- c(20, 25, 40, 55, 60)
c <- c(60, 30, 80, 50, 60)
min <- c(15, 20, 40, 55, 55)
max <- c(25, 30, 50, 65, 65)

df <- data.frame(a, b, c, min, max)

df %>% 
  mutate(b = ifelse(b < min | b > max, paste0('<font color="red">', b, '</font>'), b),
         c = ifelse(c < min | c > max, paste0('<font color="red">', c, '</font>'), c)) %>% 
 `[`(1:3) %>%
  tableHTML(escape = FALSE, rownames = FALSE, 
            widths = rep(50, 3), theme = 'scientific')

这将是结果

在此处输入图像描述

或者可能有两个条件和两种颜色:

df %>% 
  mutate(b = ifelse(b < min ,
                    paste0('<span style="background-color:#ccccff">', b, '</span>'), 
                    ifelse( b > max, paste0('<span style="background-color:#ff9999">', b, '</span>'), 
                            b)),
         c = ifelse(c < min , 
                    paste0('<span style="background-color:#ccccff">', c, '</span>'), 
                    ifelse( c > max,  paste0('<span style="background-color:#ff9999">', c, '</span>'), 
                            c))) %>% 
  `[`(1:3) %>%
  tableHTML(escape = FALSE, rownames = FALSE, 
            widths = rep(50, 3), theme = 'scientific')

你得到 :

在此处输入图像描述

这个包提供了很多格式化选项,甚至是条件格式(虽然不是这种情况),看看这里,看看你还能用这个包做什么:

表格HTML基础

条件格式

更新

有很多选项可以修改数据框中未知数量的列,我更喜欢使用这些apply函数,例如:

定义一个函数来修改列:

(在这个函数col 中是任意向量,min_col是包含下界max_col的向量,是包含上界的向量)

add_format <- function(col, min_col, max_col){
  if(!is.numeric(col)){
    return(as.character(col))
  }else{
    new_col <- ifelse(col < min_col | col > max_col, 
                      paste0('<font color="red">', col, '</font>'), col)
    return(new_col)
  }
}

现在将此函数应用于 中的所有列df,将其转换为 adata.frame然后其余的相同

df %>% 
  sapply(add_format, df$min, df$max)  %>% 
  as.data.frame() %>% 
  `[`(1:3) %>%
  tableHTML(escape = FALSE, rownames = FALSE, 
            widths = rep(50, 3), theme = 'scientific')

您还可以查看这些功能mutate_ifmutate_all它们也可以与一些游戏一起使用


推荐阅读