This example is nice but is tricky as it will modified any object from any chunk once activated because envir
contains every object
Example with another dataframe using upper case
---
output: html_document
---
```{r setup, include=FALSE}
lowercase <- function(before, options, envir) {
if (before) return()
objects <- ls(envir = envir)
for (obj in objects) {
if (class(envir[[obj]]) == "data.frame") {
colnames(envir[[obj]]) <- tolower(colnames(envir[[obj]]))
}
}
}
knitr::knit_hooks$set(lowercase = lowercase)
```
```{r}
y <- mtcars
colnames(y) <- toupper(colnames(y))
y
```
y is uppercase
```{r example, lowercase=TRUE}
num <- 1:3
chr <- letters[1:3]
(x <- data.frame(ONE = num, TWO = chr))
```
```{r did-it-work}
x
y
```
y is also modified
You can use the same idea but using the chunk option to pass the name of the object you want to modified
Providing name of object in chunk option
---
output: html_document
---
```{r setup, include=FALSE}
lowercase <- function(before, options, envir) {
if (before) return()
obj_name <- options$lowercase
if (is.character(obj_name) && exists(obj_name, where = envir)) {
colnames(envir[[obj_name]]) <- tolower(colnames(envir[[obj_name]]))
return(invisible())
}
}
knitr::knit_hooks$set(lowercase = lowercase)
```
```{r}
y <- mtcars
colnames(y) <- toupper(colnames(y))
y
```
y is uppercase
```{r example, lowercase="x"}
num <- 1:3
chr <- letters[1:3]
x <- data.frame(ONE = num, TWO = chr)
```
```{r did-it-work}
colnames(x)
colnames(y)
```
y is no more modified
Here is now an example for SQL chunk, using also the fact you can take advantage of output.var
option too.
---
output: html_document
---
```{r setup, include=FALSE}
lowercase <- function(before, options, envir) {
if (before) return()
obj_name <- options$lowercase
if (is.character(obj_name) && exists(obj_name, where = envir)) {
colnames(envir[[obj_name]]) <- tolower(colnames(envir[[obj_name]]))
return(invisible())
}
}
knitr::knit_hooks$set(lowercase = lowercase)
```
```{r}
library(dplyr)
library(dbplyr)
library(RSQLite)
con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")
colnames(mtcars) <- toupper(colnames(mtcars))
copy_to(con, mtcars)
DBI::dbListTables(con)
```
This is upper
```{r}
tbl(con, "mtcars") %>% colnames()
```
Select a column
```{sql, connection=con, output.var="MPG_up"}
SELECT MPG FROM MTCARS
```
Still upper
```{r}
colnames(MPG_up)
```
Add option to get lower colname
```{sql, connection=con, output.var="MPG_low", lowercase = "MPG_low"}
SELECT MPG FROM MTCARS
```
```{r}
colnames(MPG_low)
```
You can also use directly other options from the chunk
```{r}
lowercase <- function(before, options, envir) {
if (before) return()
if (options$lowercase && nzchar(options$output.var)) {
obj_name <- options$output.var
if (is.character(obj_name) && exists(obj_name, where = envir)) {
colnames(envir[[obj_name]]) <- tolower(colnames(envir[[obj_name]]))
return(invisible())
}
}
}
knitr::knit_hooks$set(lowercase = lowercase)
```
```{sql, connection=con, output.var="CYL_low", lowercase = TRUE}
SELECT CYL FROM MTCARS
```
```{r}
colnames(CYL_low)
```
Note all this will only work when rendering. This is because it is using knitr feature. Hooks won't do anythink when executing chunk in the Rmd inside RStudio.
Hope all this helps, and show the use of hooks to apply a function on the output df you get when using output.var
.