【问题标题】:How to use variable R code in a Knitr chunk?如何在 Knitr 块中使用可变 R 代码?
【发布时间】:2019-01-27 14:50:13
【问题描述】:

我想演示一段 R 代码的使用。但我希望代码本身是可变的。

示例两个任务:

  1. 从数据框中随机选择两个变量并将它们相加 列。
  2. 随机选择一组数字并计算它们 中位数。

定义的数据框:

<<echo=FALSE,results='hide'>>=
df <- data.frame(x1 = sample(1:5, 3), x2 = sample(1:5, 3), 
                 x3 = sample(1:5, 3), x4 = sample(1:5, 3))
@

这是最终输出代码在演示文稿中的样子:

<<foo_chunk,results='markup',echo=TRUE>>=
# You can add two columns by:
s = df$x1 + df$x3
# The median:
median(c(2, 31, 14, 5, 6))
@

目前,我正在通过以下代码实现这一点。但我无法利用可用于 knitr 代码块的漂亮代码突出显示:

<<results='asis',echo=FALSE>>=
cn <- sample(colnames(df), 2)
cat("\\# You can add two columns by:\n\n")
cat("s = df\\$", cn[1], " + df\\$", cn[2], "\n\n", sep = "")
x <- sample(1:100, 5)
cat("\\# The median:\n\n")
cat("median(c(", paste0(x, collapse = ", "), "))\n\n", sep = "")
cat("\\#\\#", median(x), "\n")
@

更新:

我找到了一种捕获输出的方法,类似于上面的foo_chunk

<<echo=FALSE,results='hide'>>=
df <- data.frame(x1 = sample(1:5, 3), x2 = sample(1:5, 3),
                 x3 = sample(1:5, 3), x4 = sample(1:5, 3))

foo <- function(cn = colnames(df), 
                x = sample(1:100, 5)) {
  return(c(
    paste0("# You can add two columns by:"),
    paste0("s = df$", cn[1], " + df$", cn[2]),
    paste0("# The Median:"),
    paste0("median(c(", paste0(x, collapse = ", "), "))")
    ))
}
@

<<code=capture.output(cat(foo(), sep="\n"))>>= 
@

此代码将提供没有任何副作用的输出(即创建一个新的临时文件,如“foo.R”)。

将不胜感激任何其他更有效的解决方案。

【问题讨论】:

  • 这个link 看起来很有希望。
  • 其中一些似乎内联而不是代码块更容易。
  • @lmo 我以为我查看了所有块参数,但错过了code= 参数。它确实看起来很有希望(here)。但我不知道如何让它在这种情况下工作。
  • @Hbat:您的新code= 解决方案很好,但可能更简单一些。可以将foo() 的结果直接作为code=foo() 传递,不需要将其组合成单个元素向量。结果的每个元素都将被视为单独的代码行。

标签: r latex knitr syntax-highlighting


【解决方案1】:

您可以通过直接调用knitr::render_latex() 定义的钩子来做到这一点(请参阅https://yihui.name/knitr/hooks/),但这看起来很棘手。为什么不把变量代码写到一个单独的文件中,并包含它呢?

例如,

\documentclass{article}

\begin{document}

<<echo=FALSE,results='hide'>>=
df <- data.frame(x1 = sample(1:5, 3), x2 = sample(1:5, 3), 
                 x3 = sample(1:5, 3), x4 = sample(1:5, 3))
@


<<echo=FALSE>>=
cn <- sample(colnames(df), 2)
x <- sample(1:100, 5)
code <- paste0(
"<<echo=TRUE>>=
# You can add two columns by
s = df$", cn[1], " + df$", cn[2], "
# The median:
median(c(", paste0(x, collapse = ", "), "))
@")
writeLines(code, "sampleCode.Rnw")
@

<<child="sampleCode.Rnw">>=
@

\end{document}

这会产生输出

编辑添加:

在问题中添加code= 可以让这更简单:

\documentclass{article}

\begin{document}

<<echo=FALSE,results='hide'>>=
df <- data.frame(x1 = sample(1:5, 3), x2 = sample(1:5, 3), 
                 x3 = sample(1:5, 3), x4 = sample(1:5, 3))

cn <- sample(colnames(df), 2)
x <- sample(1:100, 5)
code <- paste0(
"# You can add two columns by
s = df$", cn[1], " + df$", cn[2], "
# The median:
median(c(", paste0(x, collapse = ", "), "))")
@

<<code = code>>=
@

\end{document}

【讨论】:

  • 感谢您的输入,这比我找到的初始解决方案高效得多。我还在问题文本中添加了另一个没有副作用的解决方案。
猜你喜欢
  • 1970-01-01
  • 2015-09-29
  • 1970-01-01
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多