【问题标题】:Splitting knitr Chunk code and output into two different knitrouts将 knitr Chunk 代码和输出拆分为两个不同的 knitrout
【发布时间】:2014-07-31 13:40:01
【问题描述】:

knitr Chunk 选项results = "hold" 可以将输出放在Chunk Code 之后。我想知道如何将knitr 块代码和输出拆分为两个不同的knitrouts,可能带有CodeOutput 的标题。提前感谢您的帮助。

\documentclass{article} 
\begin{document}

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

期望的输出


代码

1:100
args(lm)


输出

 [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, ...) 

已编辑

我知道这可以通过放置两个块来完成,一个只显示代码,另一个只显示代码。对于长文档,这是一个额外的麻烦。我想知道这是否可以通过一些钩子获得。

【问题讨论】:

    标签: r latex knitr sweave


    【解决方案1】:

    您必须尝试格式化,但您可以通过修改source code hook 来实现。我在下面展示的实际上是对基本@9​​87654322@ 的一个非常简单的修改,即在代码前添加\\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 在 cmets 中建议的轻微修改意味着您可以将代码和输出帧分开:

    这里是setup块的修改:

    <<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 我尝试了许多不同的东西(子文档、代码外部化、purling 等),但似乎没有任何简单的方法可以将它们分成单独的输出环境。
    • @Thomas 对源挂钩的小修改通过新的kframe 完成了分离。将 '\\end{kframe}','\\begin{kframe}' 插入到您的粘贴语句中,就在输出的 \\noindent 之前。
    • @mrbcuda 谢谢!看起来不错。
    • 这太棒了。感谢您的帮助。
    【解决方案2】:

    我不确定您到底想做什么,但这会给您想要的输出吗?我把任务分成两块。首先,我推迟了对第一个块的评估,只在第二个块中打印输出。

    \documentclass{article}
    \begin{document}
    
    \subsection{Code}
    <<label=chunk1, eval=FALSE>>=
    1:10
    args(lm)
    @
    
    \subsection{Output}
    <<label=chunk2, echo=FALSE>>=
    <<chunk1>>
    @
    
    \end{document}
    

    【讨论】:

    • 第二个chunk可以表示为&lt;&lt;chunk2, ref.label="chunk1", echo=FALSE&gt;&gt;= @
    猜你喜欢
    • 1970-01-01
    • 2015-08-03
    • 2019-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多