将knitr代码块和输出分离成两个不同的knitrout

7
knitr的选项results = "hold"可以将输出放在Chunk Code之后。我想知道如何将knitr Chunk代码和输出拆分成两个不同的knitrouts,并可能带有CodeOutput的标题。谢谢您的帮助。
\documentclass{article} 
\begin{document}

<< label=Test, results = "hold" >>=
1:100
args(lm)
@ 
\end{document}

期望输出


代码

1:100
args(lm)

and


Output

 [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18
 [19]  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36
 [37]  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54
 [55]  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72
 [73]  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90
 [91]  91  92  93  94  95  96  97  98  99 100
function (formula, data, subset, weights, na.action, method = "qr", 
    model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, 
    contrasts = NULL, offset, ...) 

编辑

我知道可以通过放置两个代码块来完成此操作,一个仅显示代码,另一个仅显示结果。对于长文档,这是额外的麻烦。我想知道是否可以通过某些钩子来实现。

2个回答

5
我不确定您想要做什么,但这是否给您所需的输出?我将任务分为两个部分。首先,我推迟了第一个部分的评估,并仅在第二个部分中打印输出。
\documentclass{article}
\begin{document}

\subsection{Code}
<<label=chunk1, eval=FALSE>>=
1:10
args(lm)
@

\subsection{Output}
<<label=chunk2, echo=FALSE>>=
<<chunk1>>
@

\end{document}

5
你可以将第二个块表达为 <<chunk2, ref.label="chunk1", echo=FALSE>>@ - Thomas

5
您需要玩弄格式,但可以通过修改 source 代码钩子 来实现此目的。下面所示的实际上是基本的 render_latex 钩子 的一个非常简单的修改,在代码前添加了 \\noindent\\textbf{Code:} ,在其后添加了 \\noindent\\textbf{Output:}
\documentclass{article} 
\begin{document}

<<setup, include=FALSE>>=
knit_hooks$set(
source = function(x, options) {
      x = knitr:::hilight_source(x, 'latex', options)
      if (options$highlight) {
        if (options$engine == 'R' || x[1] != '\\noindent') {
          paste(c('\\noindent\\textbf{Code:}\\begin{alltt}', x, '\\end{alltt}', '','\\noindent\\textbf{Output:}'),
                collapse = '\n')
        } else {
          if ((n <- length(x)) > 5) x[n - 3] = sub('\\\\\\\\$', '', x[n - 3])
          paste(c('\\noindent\\textbf{Code:}',x, '','\\noindent\\textbf{Output:}'),
                collapse = '\n')
        }
      } else .verb.hook(x)
    }
)
@

Here's your first chunk.

<<chunk1, results = "hold" >>=
1:100
args(lm)
@ 

And here's another.

<<chunk2, results = "hold">>=
1:5
6:10
@ 

That seems to be it.

\end{document}

这是结果:
这里有一个由@mrbcuda在评论中提出的轻微修改建议,可以将代码和输出帧分开:
这是设置代码块的修改:
<<setup, include=FALSE>>=
knit_hooks$set(
source = function(x, options) {
      x = knitr:::hilight_source(x, 'latex', options)
      if (options$highlight) {
        if (options$engine == 'R' || x[1] != '\\noindent') {
          paste(c('\\noindent\\textbf{Code:}\\begin{alltt}', x, '\\end{alltt}', '','\\end{kframe}\\begin{kframe}\\noindent\\textbf{Output:}'),
                collapse = '\n')
        } else {
          if ((n <- length(x)) > 5) x[n - 3] = sub('\\\\\\\\$', '', x[n - 3])
          paste(c('\\noindent\\textbf{Code:}',x, '','\\noindent\\textbf{Output:}'),
                collapse = '\n')
        }
      } else .verb.hook(x)
    }
)
@

生成的输出如下:

在此输入图片描述


(+1):非常好,Thomas。不知道如何将这个 knitrout 分成两部分:一部分只包含 code,另一部分只包含 output - MYaseen208
@MYaseen208 我尝试了许多不同的方法(子文档、代码外部化、套用等),但似乎没有一种简单的方法将事物分割成单独的输出环境。 - Thomas
1
@Thomas 通过对源钩子进行小修改,可以通过新的kframe实现分离。 在输出(Output)的 \\noindent 之前的粘贴语句中插入 '\end{kframe}' ,'\begin{kframe}'。 - mrbcuda
@mrbcuda 谢谢!看起来很棒。 - Thomas
这太棒了。谢谢你的帮助。 - MYaseen208
这个工作得很好,除了像这个<< label=Test, results = "hold" >>= X <- 1:100 @一样没有输出的R Chunk代码。有什么想法吗? - MYaseen208

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接