PDF 电缆重叠 Striping/Highlighting

PDF Kable Overlapping Striping/Highlighting

我正在使用 kable 为 Rmarkdown PDF 文档生成 tables。我想根据它们的值突出显示某些单元格,每隔一行都有一个条纹。下图显示了这一点,以及我遇到的问题(取自我的 Adob​​e PDF reader)。正如您所看到的,中间一行的高光颜色(对于帽带企鹅)与其他两行不太一样。这是一个小问题,但足以让 table 看起来有点简陋,所以我希望有人能帮我找到解决办法,或者至少解释一下原因。

奇怪的是,这个问题似乎取决于我在哪个 PDF reader 中查看文档。初始图像来自 Adob​​e,但是当我在 SumatraPDF(我的 RStudio 的默认查看器)中打开文件时编织到)所有行的突出显示都是一致的(见下图)。此行为似乎不依赖于 PDF 查看器中的缩放级别,但可能与我不知道的另一个设置有关。

问题本身似乎是由浅蓝色条纹引起的,而不是高光本身,因为当我删除条纹时,所有三个高光在两个 PDF 查看器中都是均匀的。这种行为也可以在没有额外突出显示的情况下通过使用 column_spec(c(2:3), width = "2.1cm", border_right = T) 向 table 添加单元格边框来演示,如最终图像所示。在三行中的两行中,第二列的右边框被条纹覆盖(这也发生在 kableExtra 中的 built-in 条纹特征)。这里需要注意的一件有趣的事情是,确实 似乎取决于 PDF 查看器的缩放级别。下图来自 Adob​​e,采用我的默认视图 (75.5),但当我将缩放比例更改为 100 到 200 之间时,所有单元格边框都是正确的,然后再次消失。我的代码如下,感谢您的帮助!

可重现的例子

---
title: "Kable Highlighting Issue"
output: pdf_document
header-includes:
- \usepackage{booktabs}
- \usepackage{longtable}
- \usepackage{array}
- \usepackage{multirow}
- \usepackage{wrapfig}
- \usepackage{float}
- \usepackage{colortbl}
- \usepackage{pdflscape}
- \usepackage{tabu}
- \usepackage{threeparttable}
- \usepackage{threeparttablex}
- \usepackage[normalem]{ulem}
- \usepackage{makecell}
- \usepackage{titling}
- \usepackage{graphicx}
---
knitr::opts_chunk$set(echo = TRUE)
library(palmerpenguins)
library(dplyr)
library(stringr)
library(knitr)
library(kableExtra)

#create table data
table_data <- penguins %>%
  group_by(species) %>%
  summarise(bill_length_mm= round(mean(bill_length_mm, na.rm = TRUE), digits=2),
            bill_depth_mm= round(mean(bill_depth_mm, na.rm = TRUE), digits=2)) %>%
  mutate(across(everything(), as.character)) %>%
  rename(length= bill_length_mm, depth= bill_depth_mm) #_ is an escaped character in Latex

#add general table striping
#the default Kable striping feature will overwrite the highlighting, so this is an alternative way to add that
#perhaps there's something simpler?
for (row in c(1,3)){
  for (col in c(1,3)){
    table_data[row,col] <- cell_spec(table_data[row,col], "latex", background = "#ddf1f7")
  }
}

#add table highlighting if bill length > 40mm 
for (p in table_data$species){
  row <- which(table_data[1]==p)
  
  if (table_data[row, 2] > 40){
    table_data[row, 2] <- cell_spec(table_data[row, 2], "latex", background = "#00cc66")
  } else {
    table_data[row, 2] <- cell_spec(table_data[row, 2], "latex", background = "#ff704d")
  }
}

#create table
penguin_table <- kable(table_data, format = "latex", booktabs = TRUE, linesep="", escape = FALSE, align=c("l","c","c")) %>%
  kable_styling(latex_options = c("scale_down", "hold_position"), position = "center", font_size =12) %>%
  row_spec(0, bold = TRUE, hline_after = TRUE) %>%
  column_spec(1, width = "5cm") %>%
  column_spec(c(2:3), width = "2.1cm")

penguin_table

Session 信息

R version 4.0.3 (2020-10-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19042)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] kableExtra_1.3.4     knitr_1.33           stringr_1.4.0       
[4] dplyr_1.0.4          palmerpenguins_0.1.0

loaded via a namespace (and not attached):
 [1] pillar_1.4.7      compiler_4.0.3    tools_4.0.3       digest_0.6.27    
 [5] evaluate_0.14     lifecycle_1.0.0   tibble_3.0.4      viridisLite_0.3.0
 [9] pkgconfig_2.0.3   rlang_0.4.10      DBI_1.1.0         cli_2.4.0        
[13] rstudioapi_0.13   xfun_0.23         httr_1.4.2        xml2_1.3.2       
[17] generics_0.1.0    vctrs_0.3.5       systemfonts_1.0.1 webshot_0.5.2    
[21] tidyselect_1.1.0  svglite_2.0.0     glue_1.4.2        R6_2.5.0         
[25] rmarkdown_2.8     purrr_0.3.4       magrittr_2.0.1    scales_1.1.1     
[29] ellipsis_0.3.1    htmltools_0.5.0   assertthat_0.2.1  rvest_0.3.6      
[33] colorspace_2.0-0  stringi_1.5.3     munsell_0.5.0     crayon_1.3.4

呈现 pdf_document 依赖于生成中间 latex 代码,这些代码在您的 Latex 解释器中进行处理以构建文档。对于您的 pdf 文档的任何问题,我建议您查看底层乳胶代码(通过添加 keep_tex 作为输出参数。

在您的情况下,生成了 table 代码,包含以下几行:

\midrule
\cellcolor[HTML]{ddf1f7}{Adelie} & \cellcolor[HTML]{ff704d}{38.79} & \cellcolor[HTML]{ddf1f7}{18.35}\
Chinstrap & \cellcolor[HTML]{00cc66}{48.83} & 18.42\
\cellcolor[HTML]{ddf1f7}{Gentoo} & \cellcolor[HTML]{00cc66}{47.5} & \cellcolor[HTML]{ddf1f7}{14.98}\
\bottomrule

导致问题的原因是 \cellcolor 导致绘制最终 pdf 的彩色框。 Adobe reader 在以各种缩放级别很好地渲染这些时遇到了一些麻烦,并且您会发现边界框在哪个像素获得哪种颜色方面有点竞争。 'white' 行没有设置背景颜色,因此 red/green 框没有其他框可以与之竞争,因此要渲染的 space 多一点。

有关导致此问题的乳胶问题的更多背景信息,您可能需要查看 here

既然您已经手动将 cell_spec 添加到行中,为什么不明确地将偶数行的背景颜色设置为白色?

for (row in 1:nrow(table_data)){
  color = ifelse(row %%2 ==1, "#ddf1f7", "#ffffff")
  for (col in c(1,3)){
    table_data[row,col] <- cell_spec(table_data[row,col], "latex", background = color)
  }
}

这将产生一个漂亮、清晰的 table,其中至少所有 space 相互竞争的问题都得到了平等的解决。