如何在 R 中为数据框中的特定单元格/Table 着色?

How to color specific cells in a Data Frame / Table in R?

我想为以下数据框中的特定单元格着色。例如,在 inputval 列中,我想突出显示 [0.8, 0.9) 品红色范围内的单元格,以及同一列中 [0.7, 0.8) 蓝色范围内的单元格。同样,我希望值为 1 的输出列单元格为洋红色,值为 4 的输出列单元格为蓝色。对于数据框中的其余单元格,我希望它们保持白色。

我有以下可重现的代码,它只按行突出显示,并且限制我只能用洋红色和白色着色。如何按单元格添加另一种颜色?

set.seed(123)
df <- data.frame(id       = sample(1:100, 20, replace = TRUE),
                 inputval = sample(seq(0, 1, by=0.01), 20, replace = TRUE),
                 outcome  = sample(1:4, 20, replace = TRUE))

cols <- with(df, ifelse(outcome == 1, 'magenta', 'white'))

library('htmlTable')
htmlTable(as.matrix(df), col.rgroup = cols)

我意识到添加不同颜色的问题在于 with 中的 ifelse 调用限制了我只能使用洋红色和白色。我怎样才能在这里添加另一个条件?

虽然我知道是什么导致了多色问题,但我对如何只为特定单元格着色一无所知。

这与 the accepted answer to this question 的示例相同。 谢谢!

要添加其他颜色,您需要更多条件,例如如果你想为 1 的 outcome 和特定的 inputval 使用不同的颜色:

cols <- with(df, ifelse(outcome == 1,
                        ifelse(inputval == 5, 'magenta', 'red'),
                        'white')

所以这应该将 outcome == 0 的任何颜色着色为白色,如果 outcome == 1inputval == 5,它将是洋红色;其他的将是红色的。

对于您的其他问题,您可以使用 rgroupcgroup 的组合来指定要为哪个 rows/columns 着色,请参阅小插图,或在此处查看:http://cran.r-project.org/web/packages/htmlTable/vignettes/tables.html

你考虑过DT吗?

library(DT)
datatable(df, rownames = FALSE) %>%
  formatStyle(columns = "inputval", 
              background = styleInterval(c(0.7, 0.8, 0.9)-1e-6, c("white", "lightblue", "magenta", "white"))) %>%
  formatStyle(columns = "outcome", 
              background = styleEqual(c(1, 4), c("magenta", "lightblue"))) 

我下面的回答真的很蠢..正确的方法是:

此功能通过 css.cell 参数内置到 htmlTable 中:

The css.cell element allows you to add any possible CSS style to your table cells. If you provide a vector the vector it is assummed that the styles should be repeated throughout the columns. If you provide a matrix of the same size as your x argument. If have ncol(x) + 1 the first row will correspond to the rowname style. Correspondingly if the size is nrow(x) + 1 it is assummed that the first row is the header row.

所以基本上你只需要为每个单元格定义一个样式矩阵:

x <- head(cars)

## indices defining where the styles go
where <- rbind(c(2,2), c(2,1), c(5,2))
style <- c('background-color: red; color: white;',
           'border: solid 1px;',
           'font-weight: 900; color: blue;')

css.cell <- matrix('', nrow(x), ncol(x))
css.cell[where] <- style

#      [,1]                 [,2]                                  
# [1,] ""                   ""                                    
# [2,] "border: solid 1px;" "background-color: red; color: white;"
# [3,] ""                   ""                                    
# [4,] ""                   ""                                    
# [5,] ""                   "font-weight: 900; color: blue;"      
# [6,] ""                   ""                                

htmlTable(head(cars), css.cell = css.cell)

除非你来回交换,否则很难分辨,但这个 table 和下面类似的间距略有不同。 inject_div 示例看起来更居中。


有点晚了,但是@CyrusMohammadian 对我的另一个答案发表了评论,并且由于 comment/question 与这个相同,我将在此处添加答案而不是编辑我的答案一个(稍微)不同的问题。

表格可以变得复杂,每个人都有他们想要的不同功能。我认为 Max 不可能为他们所有人提供解决方案 built-in。

因此,我认为最简单的方法是(hackily)将一些 html/css 注入到您的 table 中(您也可以在 运行 htmlTable 之后执行此操作,即直接在 html 代码中,但我认为这更容易):

#' Inject div
#' 
#' Inject an html division tag with style attribute.
#' 
#' @param x a matrix or data frame
#' @param where an \code{nx2} matrix of row and column indices or vector (of
#' the form c(row, col, row, col, ...)) specifying which cells to select
#' @param style vector of character string(s) applied to each cell, recycled
#' if necessary

inject_div <- function(x, where, style = 'background-color: lightgrey; border: solid 1px') {
  if (!all(sapply(style, nzchar)))
    return(x)
  where <- matrix(where, ncol = 2L, byrow = !is.matrix(where))
  style <- rep_len(style, nrow(where))
  if (length(where) > 0)
    x[where] <- sprintf('<div style=\'%s\'>%s</div>',
                      gsub(';*$', ';', style), x[where])
  x
}

library('htmlTable')
htmlTable(inject_div(head(cars), cbind(2,2)))

htmlTable(inject_div(head(cars), where = c(2,2,2,1,5,2),
                     ## equivalently
                     # where = rbind(c(2,2), c(2,1), c(5,2))
                     style = c('background-color: red; color: white;',
                               'border: solid 1px;',
                               'font-weight: 900; color: blue;')))