• R语言
  • [已解决] knitr::kable/kableExtra 如何在指定行添加水平线

问题背景: 统计模拟常常出现不同参数,样本量和算法之间的比较,为了呈现结果,表格往往比较复杂,

问题: 我不想一个一个地粘贴数据结果放在 TeX 代码里,不知道那些统计学者是怎么做表格的?要是一个数据一个数据地粘贴,工作量也太大了!! 我打算用 kableExtra 或者 knitr::kable 定制一番

意义: 这种统计表格的样式很有代表性,值得做一个出来当作模板

目标: 用 R 代码实现下图用 LaTeX 做的表格

table

library(kableExtra)
db <- mtcars[, 1:7]
db2 <- cbind(rownames(db), db)
colnames(db2) <- c("Methods", rep(c("Bias", "RMSE"), 3), "")

kable(db2,
  format = "latex", booktabs = TRUE, escape = T, row.names = F,
  longtable = T, caption = "第1种类型的统计表格样式"
) %>%
  kable_styling(
    latex_options = c("striped", "hold_position", "repeat_header"),
    full_width = F, position = "center"
  ) %>%
  add_header_above(c(" ",
    "$\\\\sigma^2$" = 2, "$\\\\phi$" = 2,
    "$\\\\tau^2$" = 2, "$r=\\\\delta/\\\\phi$" = 1
  ), escape = F) %>%
  footnote(
    general_title = "注:", title_format = "italic", threeparttable = T,
    general = "* 星号表示的内容很长很长很长很长很长长长长长长长长长长长长长长长长长"
  )

上述 R 代码编译出来的效果见 <https://xiangyunhuang.github.io/bookdown-kableExtra/bookdown-kableExtra.pdf>
为了可重复起见,我的 R 代码中借用 mtcars 数据集替代 LaTeX 代码中的数据,为此,我还准备了

距离目标效果还差

  1. 每隔5行(任意指定行数)添加一条线作为隔断,默认似乎是空一行或者半行
  2. 表格比较长,因此需要续表,启用 longtable = T 后,默认的是英文 词 continued 而不是中文词 ,不知如何定制

附制作表格的 LaTeX 代码

% Please add the following required packages to your document preamble:
\documentclass{article}
\usepackage{booktabs}
\begin{document}

\begin{table}[]
\begin{tabular}{@{}lccccccc@{}}
\toprule
    aaa     & \multicolumn{2}{c}{$\sigma^2$} & \multicolumn{2}{c}{$\phi$} & \multicolumn{2}{c}{$\tau^2$} & $r=\delta/\phi$ \\ 
\textbf{Method}  & Bias      & RMSE          & Bias         & RMSE        & Bias          & RMSE         & aa              \\ \midrule
variogNaive & -0.106         & 0.111         & 0.026        & 0.036       & 0.101         & 0.104        & 0.2             \\ 
variogAdj   & -0.050         & 0.069         & 0.013        & 0.029       & 0.014         & 0.017        & 0.2             \\
geoNaive    & -0.166         & 0.196         & 0.037        & 0.039       & 0.149         & 0.179        & 0.2             \\
CL          & -0.053         & 0.069         & -0.001       & 0.017       & 0.015         & 0.016        & 0.2             \\
ACL2        & -0.053         & 0.069         & -0.001       & 0.017       & 0.015         & 0.016        & 0.2             \\
ACL1        & -0.052         & 0.068         & 0.005        & 0.021       & 0.015         & 0.016        & 0.2             \\ \midrule
variogNaive & -0.266         & 0.327         & 0.070        & 0.120       & 0.279         & 0.319        & 0.4             \\ 
variogAdj   & -0.053         & 0.072         & 0.013        & 0.035       & 0.002         & 0.002        & 0.4             \\
geoNaive    & -0.323         & 0.421         & 0.083        & 0.124       & 0.321         & 0.410        & 0.4             \\
CL          & -0.052         & 0.071         & -0.002       & 0.018       & 0.002         & 0.002        & 0.4             \\
ACL2        & -0.052         & 0.071         & -0.002       & 0.018       & 0.002         & 0.001        & 0.4             \\
ACL1        & -0.051         & 0.071         & 0.003        & 0.025       & 0.002         & 0.002        & 0.4             \\ \midrule
variogNaive & -0.410         & 0.412         & 0.158        & 0.160       & 0.444         & 0.453        & 0.6             \\ 
variogAdj   & -0.055         & 0.072         & 0.024        & 0.041       & 0.007         & 0.011        & 0.6             \\
geoNaive    & -0.458         & 0.466         & 0.138        & 0.142       & 0.456         & 0.458        & 0.6             \\
CL          & -0.057         & 0.071         & 0.000        & 0.022       & 0.009         & 0.010        & 0.6             \\
ACL2        & -0.057         & 0.071         & 0.000        & 0.022       & 0.009         & 0.010        & 0.6             \\
ACL1        & -0.057         & 0.072         & 0.010        & 0.028       & 0.009         & 0.011        & 0.6             \\ \midrule
variogNaive & -0.519         & 0.522         & 0.268        & 0.271       & 0.574         & 0.579        & 0.8             \\ 
variogAdj   & -0.067         & 0.092         & 0.037        & 0.049       & 0.030         & 0.041        & 0.8             \\
geoNaive    & -0.571         & 0.577         & 0.187        & 0.195       & 0.566         & 0.580        & 0.8             \\
CL          & -0.063         & 0.080         & -0.004       & 0.025       & 0.038         & 0.039        & 0.8             \\
ACL2        & -0.063         & 0.080         & -0.004       & 0.025       & 0.038         & 0.039        & 0.8             \\
ACL1        & -0.063         & 0.079         & 0.009        & 0.035       & 0.032         & 0.033        & 0.8             \\ \midrule
variogNaive & -0.587         & 0.603         & 0.437        & 0.444       & 0.667         & 0.675        & 1.0             \\ 
variogAdj   & -0.066         & 0.097         & 0.051        & 0.060       & 0.023         & 0.030        & 1.0             \\
geoNaive    & -0.655         & 0.663         & 0.243        & 0.251       & 0.653         & 0.660        & 1.0             \\
CL          & -0.071         & 0.088         & -0.007       & 0.035       & 0.027         & 0.029        & 1.0             \\
ACL2        & -0.071         & 0.088         & -0.008       & 0.031       & 0.025         & 0.028        & 1.0             \\
ACL1        & -0.071         & 0.088         & 0.009        & 0.044       & 0.023         & 0.027        & 1.0             \\ \bottomrule
\end{tabular}
\end{table}
\end{document}

用 XeLaTeX 编译后生成的 PDF 文件 table.pdf

Cloud2016 更改标题为「knitr::kable/kableExtra 如何在指定行添加水平线
  1. 解决办法是设定行与行之间的分割方式,即 linesep 参数,比如我这里设置为 linesep = c('', '', '', '', '', '\\midrule') 第六行后的分割符是画一条线
library(kableExtra)
db <- mtcars[, 1:7]
db2 <- cbind(rownames(db), db)
colnames(db2) <- c("Methods", rep(c("Bias", "RMSE"), 3), "")

kable(db2,
  format = "latex", booktabs = TRUE, escape = T, row.names = F,
  longtable = T, caption = "第1种类型的统计表格样式", 
  linesep = c('', '', '', '', '', '\\midrule')
) %>%
  kable_styling(
    latex_options = c("striped", "hold_position", "repeat_header"),
    full_width = F, position = "center",stripe_color="white"
  ) %>%
  add_header_above(c(" ",
    "$\\\\sigma^2$" = 2, "$\\\\phi$" = 2,
    "$\\\\tau^2$" = 2, "$r=\\\\delta/\\\\phi$" = 1
  ), escape = F) %>%
  footnote(
    general_title = "注:", title_format = "italic", threeparttable = T,
    general = "* 星号表示的内容很长很长很长很长很长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长"
  )

解决办法来自 <https://stackoverflow.com/questions/45409750/get-rid-of-addlinespace-in-kable> 和 knitr 的仓库, <https://github.com/yihui/knitr/blob/f467b6b27e1fee71bf0baa52ba13e048b66a215d/R/table.R#L211>

  1. 设置 repeat_header_text = "(续)" 即可,参考文档的第六页 <http://haozhu233.github.io/kableExtra/awesome_table_in_pdf.pdf>
library(kableExtra)
db <- mtcars[, 1:7]
db2 <- cbind(rownames(db), db)
colnames(db2) <- c("Methods", rep(c("Bias", "RMSE"), 3), "")

kable(db2,
  format = "latex", booktabs = TRUE, escape = T, row.names = F,
  longtable = T, caption = "第1种类型的统计表格样式",
  linesep = c("", "", "", "", "", "\\midrule")
) %>%
  kable_styling(
    latex_options = c("hold_position", "repeat_header"),
    full_width = F, position = "center", repeat_header_text = "(续)"
  ) %>%
  add_header_above(c(" ",
    "$\\\\sigma^2$" = 2, "$\\\\phi$" = 2,
    "$\\\\tau^2$" = 2, "$r=\\\\delta/\\\\phi$" = 1
  ), escape = F) %>%
  footnote(
    general_title = "注:", title_format = "italic", threeparttable = T,
    general = "* 星号表示的内容很长很长很长很长很长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长"
  )
Cloud2016 更改标题为「[已解决] knitr::kable/kableExtra 如何在指定行添加水平线