SQL code in Rnw document with knitr

时间:2016-08-31 18:02:51

标签: sql r knitr r-markdown rnw

I used the following sql code in .Rmd document. However, I want to use the same SQL code in .Rnw document.

```{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;
```

Would prefer to get code formatting and output printing facility.

1 个答案:

答案 0 :(得分:3)

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

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

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

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

有一种更优雅的方法

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

\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安装highlight中的非R代码的语法高亮显示并将目录添加到路径(Windows)。

Output