D.1 用Sweave(R+LaTeX)实现高质量排版

LaTeX是一个实现高质量排版的文档准备系统(http://www.latex-project.org),在Windows、Mac和Linux平台上都是免费的。作者在文本文件中利用个标记代码实现内容的格式化,然后用LaTeX编译器处理文档,最终得到PDF、PostScript或DVI格式的文档。

利用Sweave包可以将R代码及其输出(包括图形)嵌入到LaTeX文档中。步骤如下。

  • 用文本编辑器创建一个叫做noweb文件的文档(通常后缀是.Rnw)。这个文件中包含报告的内容、LaTeX标记代码和R代码段。每一段R代码都以<<>>=开头,以@符号结束。

  • Sweave()函数处理noweb文件,生成LaTeX文件。在这一步,R代码会被执行,然后根据设置用符合LaTeX格式的R代码和输出结果替换原来的R代码。这一步可以在R中完成,也可以在命令行中完成。

在R中是这样:

  1. Sweave("infile.Rnw")

默认情况下,Sweave("example.Rnw")会从当前工作目录中读取example.Rnw文件,然后将example.tex文件输出到同一目录中。此外,也可以这样:

  1. Sweave("infile.Rnw", syntax="SweaveSyntaxNoweb")

通过设置syntax选项可以避免一些常见的解析错误,以及跟R2HTML包之间的冲突。

在命令行中进行操作的具体过程取决于所使用的操作系统。例如,在Linux系统上,命令是这样的:

  1. $ R CMD Sweave infile.Rnw
  • 然后用LaTeX编译器处理这个LaTeX文件,创建PDF、PostScript或DVI文件。流行的LaTeX编译器有Linux平台上的TeX Live、Mac平台上的MaxTeX和Windows平台上的proTeXt。

图D-1中是整个过程的框架。

D.1 用Sweave(R+LaTeX)实现高质量排版 - 图1

图D-1 用Sweave生成出版质量报告的流程

前面说过,每一段R代码都在<<>>=@符号中。可以在<<>>=中用各种选项控制相应R代码的处理方法。例如:

  1. <<echo=TRUE, results=HIDE>>=
  2. summary(lm(Y~X, data=mydata))
  3. @

就只会输出代码,而不会输出结果,而:

  1. <<echo=FALSE, fig=TRUE>>=
  2. plot(A)
  3. @

就不会显示代码,只会显示输出中的图片。表D-1中列出了常见的选项。 表D-1 R代码块的常见选项

选  项 描  述
echo 输出中包含代码(echo=TRUE)或不包含(echo=FALSE)。默认是TRUE
eval eval=FALSE让代码不被求值或运行。默认是TRUE
fig 当输出是图形时用fig=TRUE。默认是FALSE
results 包含R代码输出(results=verbatim)、不包含输出(results=hide),或者是包含输出并假定其中有LaTeX标记(results=tex)。默认是verbatim。如果输出是用xtable包中的xtable()函数或Hmisc中的latex()函数生成的,就应该用results=tex

默认情况下,Sweave会添加LaTeX标记代码让数据框、矩阵和向量的格式更加美观。此外,可以用\Sexpr{}语句嵌入R对象。要注意,lattice图形必须嵌入到print()语句中才能正确处理。

xtable包中的xtable()函数可以更精确地格式化数据框和矩阵。此外,它还可以用于格式化其他R对象,包括lm()glm()aov()table()ts()coxph()函数生成的对象。用method(xtable)可以看到完整的列表。在用xtable()格式化R输出时,要确保在代码块选项中使用results=tex选项。

看一个例子就明白了。代码清单D-1中是一个noweb文件。这实际上是8.3节中单因子ANOVA分析的例子。LaTeX标记代码是以反斜杠(\)开头的。\Sexpr{}是一个例外,这是一个Sweave的语句。跟R有关的代码用加粗的斜体表示。

代码清单D-1 示例noweb文件(example.nrw)

  1. \documentclass[12pt]{article}
  2. \title{Sample Report}
  3. \author{Robert I. Kabacoff, Ph.D.}
  4. \date{}
  5. \begin{document}
  6. \maketitle
  7.  
  8. <<echo=false, results=hide>>=
  9. library(multcomp)
  10. library(xtable)
  11. attach(cholesterol)
  12. @
  13.  
  14. \section{Results}
  15.  
  16. Cholesterol reduction was assessed in a study
  17. that randomized \Sexpr{nrow(cholesterol)} patients
  18. to one of \Sexpr{length(unique(trt))} treatments.
  19. Summary statistics are provided in
  20. Table \ref{table:descriptives}.
  21.  
  22. <<echo = false, results = tex>>=
  23. descTable <- data.frame("Treatment" = sort(unique(trt)),
  24. "N" = as.vector(table(trt)),
  25. "Mean" = tapply(response, list(trt), mean, na.rm=TRUE),
  26. "SD" = tapply(response, list(trt), sd, na.rm=TRUE)
  27. )
  28. print(xtable(descTable, caption = "Descriptive statistics
  29. for each treatment group", label = "table:descriptives"),
  30. caption.placement = "top", include.rownames = FALSE)
  31. @
  32.  
  33. The analysis of variance is provided in Table \ref{table:anova}.
  34.  
  35. <<echo=false, results=tex>>=
  36. fit <- aov(response ~ trt)
  37. print(xtable(fit, caption = "Analysis of variance",
  38. label = "table:anova"), caption.placement = "top")
  39. @
  40.  
  41. \noindent and group differences are plotted in Figure \ref{figure:tukey}.
  42. \begin{figure}\label{figure:tukey}
  43. \begin{center}
  44.  
  45. <<fig=TRUE,echo=FALSE>>=
  46. par(mar=c(5,4,6,2))
  47. tuk <- glht(fit, linfct=mcp(trt="Tukey"))
  48. plot(cld(tuk, level=.05),col="lightgrey",xlab="Treatment", ylab="Response")
  49. box("figure")
  50. @
  51.  
  52. \caption{Distribution of response times and pairwise comparisons.}
  53. \end{center}
  54. \end{figure}
  55. \end{document}

在用R中的Sweave()函数处理完noweb文件后,用LaTeX编译器处理所得到的TeX文件,然后会生成图D-2和图D-3所示的PDF文档。

D.1 用Sweave(R+LaTeX)实现高质量排版 - 图2

图D-2 从代码清单D-1中的示例noweb文件创建的报告的第一页。在R中用Sweave()函数处理noweb文件,然后用LaTeX编译器处理得到的TeX文件,生成PDF文档

D.1 用Sweave(R+LaTeX)实现高质量排版 - 图3

图D-3 用代码清单D-1中的示例noweb文件创建的报告的第二页

关于Sweave的更多信息,请访问Sweave的主页(www.stat.uni-muenchen.de/~leisch/Sweave/)。Theresa Scott提供了一个绝佳的介绍(http://biostat.mc.vanderbilt.edu/TheresaScott)。关于LaTeX的更多信息,可以阅读“The Not So Short Introduction to LaTeX 2e”一文,可在LaTeX主页(www.latex-project.org)上找到。