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
强制换行而不是使用 makecell
和 linewrap
?...
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 创建了一个问题来引起他们的注意,所以也许 他们的 中可能有一个官方修复以后的代码。
我正在寻找 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
强制换行而不是使用 makecell
和 linewrap
?...
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 创建了一个问题来引起他们的注意,所以也许 他们的 中可能有一个官方修复以后的代码。