【问题标题】:SQL code in Rnw document with knitr带有 knitr 的 Rnw 文档中的 SQL 代码
【发布时间】:2017-01-08 10:25:55
【问题描述】:

我在.Rmd 文档中使用了以下sql 代码。但是,我想在.Rnw 文档中使用相同的 SQL 代码。

```{r label = setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, max.print = NA)
```

```{r, echo=FALSE, results='hide'}
library(DBI)
db <- dbConnect(RSQLite::SQLite(), dbname = "survey.db")
dbListTables(db)
```


```{sql, label = Q1, connection=db, tab.cap = "Table Caption"}
SELECT * 
  FROM Person;
```

希望获得代码格式化和输出打印功能。

【问题讨论】:

  • 不确定你是否已经看过这个(也没有帮助):yihui.name/knitr/demo/engines
  • 感谢@Frank 提供链接。我已经看到了,但它没有用。
  • 不确定我是否理解这个问题 - 你只是在寻找类似 @​​987654322@ 的东西吗?
  • @CL 供您发表评论。我尝试了您的代码并收到此错误:Writing to file SQL2.tex Processing code chunks with options ... 1 : echo keep.source term verbatim (label = setup, SQL2.Rnw:6) Error in match.arg(options$results, c("verbatim", "tex", "hide")) : 'arg' should be one of “verbatim”, “tex”, “hide” Calls: &lt;Anonymous&gt; -&gt; SweaveParseOptions -&gt; check -&gt; match.arg Execution halted。请有任何想法。
  • 我认为您使用的是 Sweave 而不是 knitr。请检查您的 RStudio 设置。另外,RNW 文档中似乎没有隐含的LIMIT,因此您最好在查询中添加类似LIMIT 10 的内容。一旦这有效,我们就可以转向如何很好地格式化输出的问题......

标签: sql r knitr r-markdown rnw


【解决方案1】:

将 RMarkdown 移植到 RNW 需要一些调整:

  • 当然,块分隔符需要调整:```{r, echo=FALSE} 的 RNW 等效项是 &lt;&lt;echo=FALSE&gt;&gt;=,而 RNW 块以 @ 结尾。 (见minimal RNW example。)
  • 重要的是,虽然 RMarkdown 文档中的块总是指定一个引擎,但 RNW 中的引擎隐式为 R,除非设置了选项 engine。所以```{r} 变成了简单的&lt;&lt;&gt;&gt;=,但是```{sql} 的等价物是&lt;&lt;engine="sql"&gt;&gt;=
  • RMarkdown 在嵌入 SQL 块时包含一些非常有用的魔法,请参阅knitr Language Engines: SQL on rmarkdown.rstudio.com。默认情况下,结果呈现为漂亮的表格,并且只打印前 10 个结果。在 RNW 中,我们需要自己解决这个问题。

为了在 RMarkdown 中嵌入 SQL,请注意 SQL 连接必须通过 connection 选项传递给 SQL 块。选项output.var 可用于指定将分配查询结果的对象的名称。

一个简单的解决方案(参见previous revision)只需使用output.var 将SQL 结果分配给一个对象,比如res,然后添加另一个可以很好地打印res 的R 块,例如使用xtable。但是,使用hooks 有一种更优雅的方法:

该示例使用来自sqlitetutorial.netSQLite sample database。在运行代码之前将其解压缩到您的工作目录。

\documentclass{article}

\begin{document}
\thispagestyle{empty}
<<include=FALSE>>=
library(knitr)
library(DBI)

knit_hooks$set(formatSQL = function(before, options, envir) {
  if (!before && opts_current$get("engine") == "sql") {
    sqlData <- get(x = opts_current$get("output.var"))
    max.print <- min(nrow(sqlData), opts_current$get("max.print"))
    myxtable <- do.call(xtable::xtable, c(list(x = sqlData[1:max.print, ]), opts_current$get("xtable.args")))
    capture.output(myoutput <-do.call(xtable::print.xtable, c(list(x = myxtable, file = "test.txt"), opts_current$get("print.xtable.args"))))
    return(asis_output(paste(
      "\\end{kframe}", 
      myoutput,
      "\\begin{kframe}")))
  }
})

opts_chunk$set(formatSQL = TRUE)
opts_chunk$set(output.var = "formatSQL_result")
opts_chunk$set(max.print = getOption("max.print"))

@

<<echo=FALSE, results="hide">>=
db <- dbConnect(RSQLite::SQLite(), dbname = "chinook.db")
@

<<engine = "sql", connection=db, max.print = 8, xtable.args=list(caption = "My favorite artists?", label="tab:artist"), print.xtable.args=list(comment=FALSE, caption.placement="top")>>=
SELECT *  FROM artists;
@

\end{document}

添加了一个新的块挂钩formatSQL。 (只要对应的块选项不是NULL,块挂钩就会运行。)在带有engine="sql" 的块之后,它将SQL 结果读入sqlData。然后,它使用xtable 打印结果的第一行max.print

默认情况下,块钩子formatSQL被激活(即它被全局设置为TRUE)并且SQL结果存储在formatSQL_result中。块选项max.print 控制要打印的行数(将其设置为Inf 以打印所有行,总是)。

xtable 制作的表格是高度可定制的。块选项xtable.args 被传递给xtableprint.xtable.args 被传递给print.xtable。在示例中,这些选项用于设置标题、标签和禁止 xtable 的默认注释。

在生成的 PDF 下方。请注意,RNW requires 中非 R 代码的语法高亮显示安装 highlight 并将目录添加到路径 (Windows)。

【讨论】:

  • 伟大的@CL。奇迹般有效。如果您指导如何将标题放在桌子的顶部,将不胜感激。非常感谢您的帮助。
  • @MYaseen208 只需将caption.placement="top" 传递给print.xtable
  • 谢谢@CL。您的帮助。还有两件事要修改,knitr 中的knitr2pdf 命令在控制台上显示xtable 输出,这不是必需的。还想知道如何在全局而非本地使用caption.placement="top"connection=db。任何想法。
  • @MYaseen208 1) xtable 控制台输出:见编辑。 2)见?print.xtable:全局选项xtable.caption.placement 3)全局connection=db:不要以为这是可能的。
猜你喜欢
  • 2018-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-07
  • 2014-01-04
  • 2013-10-05
  • 1970-01-01
  • 2021-09-23
相关资源
最近更新 更多