【问题标题】:How to color specific cells in a Data Frame / Table in R?如何为 R 中的数据框/表中的特定单元格着色?
【发布时间】:2015-07-09 17:00:23
【问题描述】:

我想为以下数据框中的特定单元格着色。例如,在 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 相同。 谢谢!

【问题讨论】:

标签: css r formatting


【解决方案1】:

你考虑过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"))) 

【讨论】:

  • 哇!就这么简单,谢谢!如果我碰巧知道要更改颜色的每一列中的行号,我将如何指定它?例如,在outcome 列中,假设第 1、2、4 行是蓝色,第 3、5、6 行是洋红色。 formatstyle 的参数会类似于 background = styleEqual(c(1,2, 4, 3, 5, 6), c(rep("lightblue", 3),rep("magenta", 3)) 吗?当然,我不会明确写出行号。我会让向量blue 存储蓝色的行号,向量magenta 存储洋红色的行号。
  • 我能够更轻松地根据单元格中的值而不是行号来突出显示,就像您对列 outcome 所做的那样。再次感谢您!那张桌子很漂亮!
  • 您是如何将整个表格整合到一张图片中的?当我从 Rstudio 导出表格时,它的一部分丢失了。
  • 您可以在datatable 中设置options = list(paging = FALSE),打开您的tempdir(),然后在浏览器中打开相应的html 并使用Nimbus 或其他截屏工具从浏览器中截屏。跨度>
  • +1 谢谢。在 Libre Office 上选择全部 -> 复制 -> 粘贴可以正常工作,并保持颜色和大部分表格格式以供任何人将来参考。 Nimbus 或类似的东西最适合较小的桌子,保持图像质量。
【解决方案2】:

我下面的答案真的很愚蠢..这是正确的方法:

此功能通过css.cell 参数内置于htmlTable

css.cell 元素允许您向表格单元格添加任何可能的 CSS 样式。如果您提供向量,则假定样式应在整个列中重复。如果您提供与 x 参数大小相同的矩阵。如果有ncol(x) + 1,第一行将对应rowname 样式。相应地,如果大小为nrow(x) + 1,则假定第一行为标题行。

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

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)

除非您来回交换,否则很难分辨,但此表中的间距与下面的类似表中的间距略有不同。 inject_div 示例看起来更加居中。


有点晚了,但@CyrusMohammadian 对我的其他答案发表了评论,并且由于评论/问题与此相同,我将在此处添加答案,而不是编辑我的答案(略)不同的问题。

表格可能会变得复杂,每个人都有他们想要的不同功能。我认为Max 不可能为它们都内置解决方案。

因此,我认为最简单的方法是(hackily)将一些 html/css 注入到您的表中(您也可以在运行 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;')))

【讨论】:

    【解决方案3】:

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

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

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

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

    【讨论】:

    • 谢谢!指定我需要的 rgroup 和 cgroup 组合的工作示例是什么?我相信您提供的链接没有选择不同单元格的明确示例。
    • 抱歉,您可能需要阅读文档并尝试一些操作。
    猜你喜欢
    • 2019-04-29
    • 2018-01-10
    • 1970-01-01
    • 2017-03-08
    • 2019-02-16
    • 2016-03-08
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    相关资源
    最近更新 更多