Skip to content

Commit

Permalink
indent 4 spaces for Sweave chunks
Browse files Browse the repository at this point in the history
  • Loading branch information
yihui committed Apr 16, 2012
1 parent 5795d8c commit 14cbb00
Showing 1 changed file with 17 additions and 25 deletions.
42 changes: 17 additions & 25 deletions source/11-auto-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@

要使用文学化编程,必须得有一些设定的规则来标记哪些是代码,哪些是正文,否则这事儿没法进行。最早的语法是这样:用`<<>>=`来标记代码的开始,用`@`标记正文的开始,凡是遇到这两类符号,也就意味着要换频道了,下文要标记为代码或正文。例如,

```
@
hello, I will do 1 + 2 next:
@
hello, I will do 1 + 2 next:

<<foo>>=
1 + 2
@
<<foo>>=
1 + 2
@

OK, I'm done now.
```
OK, I'm done now.

这一块文字中包含两段正文和一段代码。编译它的时候,计算机根据前面的规则就知道`<<>>=`下面的是可以运算的代码,而`@`下面是正文,不能当作代码运行。这就是文学化编程的基本思想,它可以很容易移植到自动化报告中来,下面我们再详细说里面的细节问题。Sweave借用了这个思想,把R代码嵌入报告中,编译报告的时候R代码被执行,源文档中的R代码在输出的时候被替换为相应的运行结果,这些结果和原来的报告正文混合起来就形成了一篇有结果的报告。这样,我们只需要维护包含源代码的源文档,让结果文档自动生成,而不要手工运行代码并复制粘贴结果到文档里,这样做既累人又容易出错。记住,只有源代码是可以信赖的。注意我并不是说它的结果一定是对的,或者源代码一定是对的,代码当然可能是错的,但源代码要是错了我们可以检查出来,而要是人工操作哪里出了岔子就很难查错,比如你本来应该点这个按钮,结果你当时点了另一个,如果没有完整的屏幕录像,恐怕追溯结果的来源时就比较困难了。源代码通常是文本文件,可以放入版本控制如GIT或SVN,记录完整的修改历史。附带说一句,版本控制(Version Control)工具是忍者必备工具,后面会用专门用一章讲,你要是不会这东西的话,别跟别人说你看过这本书。

Expand Down Expand Up @@ -159,23 +157,19 @@ knit_hooks$set(par = function(before, options, envir) {

假设我们新造的一个选项叫`par`,它不是**knitr**自带的选项,且跟上面定义的钩子函数同名,那么对下面这个代码段来说,它被执行之前,R会先用`par()`函数设置图形边距参数,因为这是钩子函数定义要执行的任务:

```
<<good-margin, par=TRUE>>=
plot(1)
@
```
<<good-margin, par=TRUE>>=
plot(1)
@

注意钩子函数被触发的条件是相应的选项取值非空,所以这里`par`取值`TRUE``FALSE``123`都无所谓。代码段钩子让我们可以把常见的次要任务抽象出来,用一个代码段选项去控制它们的执行。比如上面设定图形边距就是一个非常常见的任务,但要是把这样的代码在每个代码段中的都写一遍的话,就太啰嗦了,而且重复敲代码是大忌!每当你想复制粘贴一段代码的时候都要三思,我真的不需要想办法把这段代码抽象出去吗?

输出钩子用来装裱输出,**knitr**的透明性也体现在这一类钩子上,它可以把R的各类输出都交给用户,让用户决定怎么处理这些输出。所有可能的输出有:源代码、普通文本、警告消息、普通消息、错误消息和图形。每一种有一个对应的钩子函数,这些函数接收R的输出,以一定的形式包装它们,再返回输出来。以源代码为例,它的钩子名为`source`,如果我们定义:

```
<<source-hook>>=
knit_hooks$set(source = function(x, options) {
paste('\\begin{myEnvironment}', x, '\\end{myEnvironment}')
})
@
```
<<source-hook>>=
knit_hooks$set(source = function(x, options) {
paste('\\begin{myEnvironment}', x, '\\end{myEnvironment}')
})
@

那么在输出的时候所有R源代码都会被放在`myEnvironment`环境中(当然,你得事先定义好这个环境,不然LaTeX会报错)。钩子函数中,`x`是当前代码段的输出,`options`是所有选项的一个列表。

Expand Down Expand Up @@ -203,11 +197,9 @@ knit_hooks$set(source = function(x, options) {

在LyX中输入R代码可以用快捷键`Ctrl + L`,然后按前面介绍的LaTeX类语法写(为什么是LaTeX语法?):

```
<<hello-world, echo=FALSE>>=
print('hello world!')
@
```
<<hello-world, echo=FALSE>>=
print('hello world!')
@

事实上**knitr**包的大多数PDF手册都是用LyX写的,读者可以在这里找到它们:

Expand Down

0 comments on commit 14cbb00

Please sign in to comment.