Rmarkdown转中文pdf中遇到的问题

1.前言

因工作需要最近一直在折腾使用rmd来实现自动分析报表的web服务,其间也尝试过使用其它途径来实现比如直接编写html的模板,不过最终还是发现使用rmd是最好的途径。不过在生成pdf文件的时候还是遇到了不少问题,尤其是完全没接触过latex,真实的配置中确又少不了,然而官方的示例文档中又会有类似这样的解释。。。
Rmarkdown转中文pdf中遇到的问题_第1张图片
这里必须吐槽,不是不想百度,很多时候只想快速解决问题,对latex真是没一丁点学习的欲望,而碰到这种情况就是给你希望又确说:你得再走两步自个儿解决问题。铺垫就到这,以下仅列举个人遇到的一些问题仅供参考,系统环境为ubuntu16,其它环境会如何尚不清楚。

2.软件要求

latex

sudo apt-get install texlive-latex-base
sudo apt-get install latex-cjk-all
sudo apt-get install texlive-latex-extra
sudo apt-get install texlive-xetex
...

如果上述安装后,在生成pdf文件时仍然报错:! LaTeX Error: ...,如果缺少*.sty库,直接用apt-cache search ...找到对应插件,安装即可。

pandoc

Rmd文件在转化为pdf的过程中需要用到pandoc,而低版本的pandoc可能不支持生成pdf文件,因此需要确保,服务器或本地环境已安装了pandoc并且是相对高的版本。可以通过命令行直接调用pandoc将.md文件或.html文件转换为pdf。基本使用命令如下:

  • md转pdf: pandoc somefile.md -o somefile.pdf, 指定编译器(包含中文)pandoc --latex-engine=xelatex somefile.md -o somefile.pdf
  • html转pdf: 同上。

当然这也提供了一个生成pdf的途径即:使用knitr生成html文件,再使用pandoc转换为pdf(实际上这和直接生成pdf没有本质区别)。
Attentation: 在命令行中使用pandoc转换由knitr生成的html文件为pdf时可能会报错如下:

Stack space overflow: current size 16777216 bytes.
Use `+RTS -Ksize -RTS' to increase it.
Error: pandoc document conversion failed with error 2

解决方法为在.rmd 文件的头部添加如下配置:

  html_document:
      pandoc_args: ["+RTS", "-K100000000", "-RTS"]

或者在命令行中写成这样:

pandoc RTS -K100000000 -RTS --latex-engine=xelatex somefile.html -o somefile.pdf

参考链接:
https://stackoverflow.com/questions/25599860/how-to-increase-stack-space-overflow-for-pandoc-in-r
http://www.cnblogs.com/liuyangnuts/archive/2013/04/23/3038354.html
https://superuser.com/questions/1073291/pandoc-has-stack-size-error/1073707
http://www.cnblogs.com/airbird/p/6160223.html

3.文字编码

中文编码的坑在任何时候都少不了,如果不加配置,直接在头文件中设置output: pdf_document,然后点击‘knit’那个毛线团的小按钮,或者命令行中调用如下命令:

R -e 'rmarkdown::render("some.rmd", output_format = "all", output_dir = "some.pdf")'

如果文件中使用了中文,那么应该会出现第一个编码问题,错误信息大概就像下面(标题中使用了“年”这个字),解决方式有两种。

! Package inputenc Error: Unicode char 年 (U+5E74)
(inputenc)                not set up for use with LaTeX.

See the inputenc package documentation for explanation.
Type  H   for immediate help.
 ...   

3.1 使用中文模板

rticles包提供了适用于各类场景的rmd模板,安装以后便可以选择支持中文的模板,在rstudio菜单栏中依次选择file->new file->R Markdown,然后选择下图所示的模板。当然模板本身就包含了如何使用中文的说明,本文前言中的那段话就摘自此模板。大佬的语言风格就是这么个性。
Rmarkdown转中文pdf中遇到的问题_第2张图片

3.2 引用tex配置文件

由于应用上需要同时生成html以及pdf,显然上述的模板并不能满足要求。此时可以通过在头文件中引用tex配置文件的方式解决问题:

output:
  pdf_document:
      latex_engine: xelatex
      includes:
        in_header: head.tex

head.tex中的内容如下,不懂latex必须承认是网上抄的,第一句解决中文问题,第二句实现首行缩进。

\usepackage{ctex} 
\parindent 2em

参考链接:
https://www.jianshu.com/p/a97b4a9f6d5b

4.图片乱码

文字解决了但是事儿没完,这是关于编码的第二个坑,就像下面这样,用ggplot2生成的图片中的中文字符全部变成了‘…’的形式。
Rmarkdown转中文pdf中遇到的问题_第3张图片
怀疑过字体问题、tex设置问题、操作系统以及人生。。。最终通过仔细查阅官方文档以及stackoverflow最终发现图形设备需要额外指定,方式为在头文件中加入如下’dev’的配置,当然也可以设置为其它的图形设备。

output:
  pdf_document:
      latex_engine: xelatex
      dev: cairo_pdf
      includes:
        in_header: head.tex

Rmarkdown转中文pdf中遇到的问题_第4张图片
其中图形设备可以替换为下列中的任何一个:bmp, postscript, pdf, png, svg, jpeg, pictex, tiff, win.metafile, cairo_pdf, cairo_ps, CairoJPEG, CairoPNG, CairoPS, CairoPDF, CairoSVG, CairoTIFF, Cairo_pdf, Cairo_png, Cairo_ps, Cairo_svg, tikz and a series of quartz devices including quartz_pdf, quartz_png, quartz_jpeg, quartz_tiff, quartz_gif, quartz_psd, quartz_bmp。
过这个坑花了不少时间,然而这并不是结束。当然图片乱码的问题除此之外也可以使用showtext解决。

参考链接:
问题:https://github.com/yihui/knitr/issues/889
文档:https://yihui.name/knitr/demo/graphics/
文档:https://yihui.name/knitr/options/#plots
https://blog.csdn.net/u012111465/article/details/79945372

5.图片错位

在转换为pdf的时候,有时候图片不会显示在放置它的位置,而是跑到了latex认为合适的位置。解决方式为设置参数fig.pos='H',可以像下面那样设置为全局参数。

knitr::opts_chunk$set(fig.pos='H')

参考链接
问题:https://stackoverflow.com/questions/29696172/how-to-hold-figure-position-with-figure-caption-in-pdf-output-of-knitr
问题:https://stackoverflow.com/questions/16626462/figure-position-in-markdown-when-converting-to-pdf-with-knitr-and-pandoc

6.表格样式

6.1 kable

在knitr的众多功能中,对图片的支持是相当丰富的。但是对表格似乎就不这么友好了,除了kable函数外一个也没有。尤其是转换为pdf以后,表格的样式变化很大,同时通过css修饰的样式也完全不能保留。
html:
Rmarkdown转中文pdf中遇到的问题_第5张图片
pdf:
Rmarkdown转中文pdf中遇到的问题_第6张图片

一种解决方式是采用kableExtra对表格样式进行修饰,并且通过knitr::is_html_output()判断输出格式进行对应表格的绘制:

'''{r}
library(knitr)
library(kableExtra)
library(magrittr)
tb <- iris[1:6,c(1,2,3)]

if (is_html_output()) {
  kable(
  tb, format = "html", digits = 0, longtable = TRUE,
  booktabs = FALSE, align = c('l', 'c', 'c'),
  caption = 'table1.1 iris'
  )  %>% kable_styling(
    full_width = TRUE
  )
} else {
  kable(
  tb, format = "latex", digits = 0, longtable = TRUE, 
  # padding = 2, 
  booktabs = TRUE, align = c('l', 'c', 'c'),
  caption = 'iris' 
  ) %>% kable_styling(
    full_width = TRUE,
    latex_options = c("striped", "hold_position", "scale_down")
  ) 
}
'''

html:
Rmarkdown转中文pdf中遇到的问题_第7张图片

pdf:
Rmarkdown转中文pdf中遇到的问题_第8张图片

6.2 xtable

xtable是另一种选择。

'''{r results="asis"}
library(xtable)
tb <- iris[1:6,c(1,2,3)]
print(
  xtable(tb, caption = 'table 1.1 iris'), type = 'html', 
  caption.placement = 'top'
  ) 
'''

Rmarkdown转中文pdf中遇到的问题_第9张图片

参考链接
https://stackoverflow.com/questions/15258233/using-table-caption-on-r-markdown-file-using-knitr-to-use-in-pandoc-to-convert-t
https://stackoverflow.com/questions/21397407/knitr-r-markdown-and-xtable-xtable-tables-within-html-table

7.参考资料

其它参考资料
how-to-convert-r-markdown-to-pdf
how-to-convert-html-to-pdf-using-pandoc
http://www.bagualu.net/wordpress/archives/6182

你可能感兴趣的:(R)