KableExtra:当与 \makecell 结合使用时,colortbl 的 \cellcolor 不会填充整个单元格

KableExtra: colortbl's \cellcolor not filling entire cell when used in combination with \makecell

我正在寻找 known issue 的变通解决方案,其中 colortbl 包中的 \cellcolor 不能与 \makecell 一起正常工作。如前所述,Latex 中可能已经存在解决方法,但我希望在使用 rmarkdown 生成 pdf 时根据 R 包 kableExtra 找到解决方案。这是截图;可以看出,有些单元格没有完全填满。

这是 rmarkdown 中的一个可重现性最低的示例:

library(kableExtra)
library(tidyverse)
# Data --------------------------------------------------------------------
df <- tribble(
  ~col1, ~col2, 
  "really long text that needs to be broken into multiple lines so it can fit", 4,
  "really long text that needs to be broken", 4,
  "really long text that needs a fix", 4,
) %>%
  modify_at(
    .x = .,
    .at = 1,
    .f = stringr::str_wrap,
    width = 25
  )
# Table -------------------------------------------------------------------
df %>%
  mutate(across(.cols = 1, .fns = linebreak, align = "l")) %>%
  kbl(x = ., escape = FALSE) %>%
  row_spec(row = 1:3, background = "#e5e5e5")

一种可能的修复方法是在 YAML 中指定 keep_tex: true 并在使用 pandoc 之前手动修复 .tex 文件中的问题。但是我生成了很多表,这可能效率不高。任何有关潜在解决方法的建议都将不胜感激。

为什么不使用 column_spec 强制换行而不是使用 makecelllinewrap?...


library(tibble)
library(dplyr) #for the pipe
library(kableExtra)


df <- tribble(
  ~col1, ~col2, 
  "really long text that needs to be broken into multiple lines so it can fit", 4,
  "really long text that needs to be broken", 4,
  "really long text that needs a fix", 4,
)


kbl(df) %>%
  column_spec(1, width = "30mm") %>% 
  row_spec(row = 1:3, background = "#e5e5e5")

另一个适用于 我的用例 的解决方案(其中 column_spec(width) 失败)基于 post 中的 leandriis comment。具体来说,我们将 \colorbox 命令包裹在 \makecell 命令周围以获得完全彩色的单元格。例如 \colorbox[HTML]{hexcode}{\makecell{text}}。这需要我们创建自己的自定义 linebreak 函数,它不仅将我们的文本包装在 \makecell 中,还将乳胶代码包装在 \colorbox.

# Custom linebreak --------------------------------------------------------
linebreak_custom <- function(x, align = "l", linebreaker = "\n") {
  ifelse(
    # If '\n' is detected in a string, TRUE, or else FALSE
    test = str_detect(x, linebreaker),
    # For TRUE's, wrap text in \makecell and then in \colorbox
    yes = paste0(
      "\cellcolor[HTML]{e5e5e5}{\colorbox[HTML]{e5e5e5}{\makecell[", align, "]{",
      str_replace_all(x, linebreaker, "\\\\"), "}}}"
    ),
    # Return as is if no '\n' detected
    no = x
  )
}
# Data --------------------------------------------------------------------
df <- tribble(
  ~col1, ~col2,
  "really long text that needs to be broken into multiple lines so it can fit", 4,
  "really long text that needs to be broken", 4,
  "really long text that needs a fix", 4,
) %>%
  modify_at(
    .x = .,
    .at = 1,
    .f = stringr::str_wrap,
    width = 25
  )
# Table -------------------------------------------------------------------
df %>%
  mutate(across(.cols = 1, .fns = linebreak_custom, align = "l")) %>%
  kbl(x = ., escape = FALSE) %>%
  row_spec(row = 1:3, background = "#e5e5e5")

这会产生所需的输出:

如前所述,此解决方案对于 kableExtra 的未来版本可能不稳健(因为它涉及,坦率地说,“破解”源代码),并且上面 Peter 建议的解决方案仍然应该是在许多用例中更好。 我已经通过 Github 创建了一个问题来引起他们的注意,所以也许 他们的 中可能有一个官方修复以后的代码。