如何在 Knitr 块中使用可变 R 代码?

How to use variable R code in a Knitr chunk?

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

示例两个任务:

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

定义的数据框:

<<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")。

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

您可以通过直接调用 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}