R Kable:如何根据行中其他值的比例对值使用条件格式

R Kable:如何根据行中其他值的比例对值使用条件格式,r,knitr,kable,kableextra,R,Knitr,Kable,Kableextra,我想在kable/kableExtra中使用条件格式,根据行中的范围为值着色。我在列中找到了很多关于如何按值执行的示例,但我很难按行执行 以下是按列值列出的示例: require(tidyverse) require(knitr) require(kableExtra) iris[1:10, ] %>% mutate_if(is.numeric, function(x) { cell_spec(x, bold = T, co

我想在
kable
/
kableExtra
中使用条件格式,根据行中的范围为值着色。我在列中找到了很多关于如何按值执行的示例,但我很难按行执行

以下是按列值列出的示例:

require(tidyverse)
  require(knitr)
  require(kableExtra)
  iris[1:10, ] %>%
    mutate_if(is.numeric, function(x) {
      cell_spec(x, bold = T, 
                color = spec_color(x, end = 0.9),
                font_size = spec_font_size(x))
    }) %>%
    mutate(Species = cell_spec(
      Species, color = "white", bold = T,
      background = spec_color(1:10, end = 0.9, option = "A", direction = -1)
    )) %>%
    kable(escape = F, align = "c") %>%
    kable_styling(c("striped", "condensed"), full_width = F)


但是,我希望颜色由每行中的值范围决定。当然,在这个例子中,第一列总是最大的,最后一列是最小的,所以它们都朝那个方向走,但在我的实际数据中,最高值和最低值的位置在每一行的不同列中。

您可以修改
spec\u color
spec\u font\u size
函数,以便处理行而不是列(只需在RStudio中键入F2即可获得原始源代码):

编辑:根据您的最后一个问题,可以使用
rowwise
和新的
c\u-overs
功能进一步改进/压缩这一点:

iris[1:10,] %>%  rowwise() %>% 
                 mutate(rowmin = min(c_across(is.numeric)),
                        rowmax = max(c_across(is.numeric))) %>%
                 mutate(across(is.numeric,
                        ~cell_spec(., bold = T, 
                                   color = spec_color_row(.,rowmin, rowmax, end = 0.9),
                                   font_size = spec_font_size_row(.,rowmin ,rowmax)))) %>%  
                 select(-rowmin,-rowmax) %>%
                 kable(escape = F, align = "c") %>%
                 kable_styling(c("striped", "condensed"), full_width = F)
然而,我还没有完全摆脱
rowmin
/
rowmax
中间计算,因为列操作与
dplyr
中的行操作一样容易。这就是为什么我喜欢@dww解决方案来转换数据帧以克服这个困难


您可以在行方向上对值使用
应用

df = head(iris,10)
fn = function(x) cell_spec(x, bold = T, color = spec_color(x, end = 0.9),
                          font_size = spec_font_size(x))    
df[, 1:4] = t(apply(df[,1:4], 1, fn))    
df %>%
  kable(escape = F, align = "c") %>%
  kable_styling(c("striped", "condensed"), full_width = F)

太简单了!太好了,谢谢你。有没有一种方法可以使用单个函数来实现,而不需要为
iris\u cols
创建中间对象并更新
数据
对象?如果有一个在管道链中工作的单一函数就太好了。请参见我的编辑,去掉了iris_cols,仍然需要rowmin rowmax中间计算,因为行操作与dplyr的列操作一样困难。
data %>%  mutate(across(iris_cols,
                        ~cell_spec(., bold = T, 
                                      color = spec_color_row(.,rowmin, rowmax, end = 0.9),
                                      font_size = spec_font_size_row(.,rowmin ,rowmax)))) %>%  
  kable(escape = F, align = "c") %>%
  kable_styling(c("striped", "condensed"), full_width = F)
iris[1:10,] %>%  rowwise() %>% 
                 mutate(rowmin = min(c_across(is.numeric)),
                        rowmax = max(c_across(is.numeric))) %>%
                 mutate(across(is.numeric,
                        ~cell_spec(., bold = T, 
                                   color = spec_color_row(.,rowmin, rowmax, end = 0.9),
                                   font_size = spec_font_size_row(.,rowmin ,rowmax)))) %>%  
                 select(-rowmin,-rowmax) %>%
                 kable(escape = F, align = "c") %>%
                 kable_styling(c("striped", "condensed"), full_width = F)
df = head(iris,10)
fn = function(x) cell_spec(x, bold = T, color = spec_color(x, end = 0.9),
                          font_size = spec_font_size(x))    
df[, 1:4] = t(apply(df[,1:4], 1, fn))    
df %>%
  kable(escape = F, align = "c") %>%
  kable_styling(c("striped", "condensed"), full_width = F)