From 7fda6915a1102aeaed20319ee8f84d84f9c199a9 Mon Sep 17 00:00:00 2001 From: stephhazlitt Date: Fri, 31 Jan 2020 16:33:46 -0800 Subject: [PATCH 1/4] start getting started vig --- vignettes/glue.Rmd | 135 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 vignettes/glue.Rmd diff --git a/vignettes/glue.Rmd b/vignettes/glue.Rmd new file mode 100644 index 0000000..b46aa8d --- /dev/null +++ b/vignettes/glue.Rmd @@ -0,0 +1,135 @@ +--- +title: "Getting started with glue" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Get started with glue} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set(collapse = TRUE, + comment = "#>", + messages = FALSE, + warning = FALSE) + +library(glue) +``` + +The `glue` package contains functions for glueing together character strings and R code. + +```{r eval = FALSE} +# Install the released version of the glue package from CRAN: +install.packages("glue") + +# Load the glue package +library(glue) +``` + + +## Glueing character strings + +`glue()` can be used to glue together character strings, such as text: +```{r} +glue("glueing", "some", "text", "together") +``` + +The default for `glue()` is glueing with _no_ separator— you can provide a separator with the `.sep` argument: +```{r} +glue("glueing", "some", "text", "together", .sep = " ") +glue("glueing", "some", "text", "together", .sep = ".") +``` + +You can optionally combine strings with `+`: +```{r} +glue("glueing") + " some" + " text" + " together" +``` + + +## Glueing & formatting + +Leading whitespace and blank lines from the first and last lines are automatically trimmed with `glue()`, letting you indent the strings naturally in code: +```{r} +glue(" + A formatted string + Can have multiple lines + with additional indention preserved + ") +``` + +An additional newline can be used if you want a leading or trailing newline. +```{r} +glue(" + + leading or trailing newlines can be added explicitly + + ") +``` + +`\\` at the end of a line continues it without a new line: +```{r} +glue(" + A formatted string \\ + can also be on a \\ + single line + ") +``` + + +You can add colour to your strings with `glue_col()`: +```{r} +library(crayon) + +glue_col("{blue glueing blue text together}") +glue_col("This ", "{red text}", " is not", " {blue blue}") + +``` + + +## Glueing character strings _with_ R code + +Glue evaluates R code provided in curly braces and glues the result together with character strings. + +Variables can be passed directly into strings: +```{r} +name <- "glue" +glue('We are learning how to use the {name} R package.') +``` + +R expressions can be passed into strings: +```{r} +release_date <- as.Date("2017-06-13") +glue('The first version of the glue package was released on a {format(release_date, "%A")}.') +``` + + +## Glue with a data frame + +`glue_data()` can be used to work with a list or data frame: +```{r message=FALSE} +library(dplyr) + +glue_data(head(starwars), "{name} is from the planet {homeworld}.") +``` + +## Glueing with `dplyr` & `ggplot2` + +`glue()` can be used with `dplyr` & `ggplot2` pipelines: +```{r, message = FALSE,fig.width=7} +library(dplyr) +library(ggplot2) + +starwars %>% + mutate(new_x_label = glue("{name} ({species})")) %>% + filter(height > 200) %>% + ggplot(aes(new_x_label, height)) + + geom_col() + + coord_flip() +``` + + + +## Additional Vignettes + + - [Speed of glue](https://glue.tidyverse.org/articles/speed.html) + - [Transformers](https://glue.tidyverse.org/articles/transformers.html) From 168f1c6858b22e03ae015ef2571ad90a39e864a8 Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Thu, 26 Jan 2023 11:21:54 -0600 Subject: [PATCH 2/4] Use visual editor --- vignettes/glue.Rmd | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/vignettes/glue.Rmd b/vignettes/glue.Rmd index b46aa8d..b065804 100644 --- a/vignettes/glue.Rmd +++ b/vignettes/glue.Rmd @@ -26,29 +26,31 @@ install.packages("glue") library(glue) ``` - ## Glueing character strings -`glue()` can be used to glue together character strings, such as text: +`glue()` can be used to glue together character strings, such as text: + ```{r} glue("glueing", "some", "text", "together") ``` -The default for `glue()` is glueing with _no_ separator— you can provide a separator with the `.sep` argument: +The default for `glue()` is glueing with *no* separator--- you can provide a separator with the `.sep` argument: + ```{r} glue("glueing", "some", "text", "together", .sep = " ") glue("glueing", "some", "text", "together", .sep = ".") ``` You can optionally combine strings with `+`: + ```{r} glue("glueing") + " some" + " text" + " together" ``` - ## Glueing & formatting Leading whitespace and blank lines from the first and last lines are automatically trimmed with `glue()`, letting you indent the strings naturally in code: + ```{r} glue(" A formatted string @@ -58,6 +60,7 @@ glue(" ``` An additional newline can be used if you want a leading or trailing newline. + ```{r} glue(" @@ -67,6 +70,7 @@ glue(" ``` `\\` at the end of a line continues it without a new line: + ```{r} glue(" A formatted string \\ @@ -75,8 +79,8 @@ glue(" ") ``` - You can add colour to your strings with `glue_col()`: + ```{r} library(crayon) @@ -85,27 +89,28 @@ glue_col("This ", "{red text}", " is not", " {blue blue}") ``` - -## Glueing character strings _with_ R code +## Glueing character strings *with* R code Glue evaluates R code provided in curly braces and glues the result together with character strings. Variables can be passed directly into strings: + ```{r} name <- "glue" glue('We are learning how to use the {name} R package.') ``` R expressions can be passed into strings: + ```{r} release_date <- as.Date("2017-06-13") glue('The first version of the glue package was released on a {format(release_date, "%A")}.') ``` - ## Glue with a data frame `glue_data()` can be used to work with a list or data frame: + ```{r message=FALSE} library(dplyr) @@ -115,6 +120,7 @@ glue_data(head(starwars), "{name} is from the planet {homeworld}.") ## Glueing with `dplyr` & `ggplot2` `glue()` can be used with `dplyr` & `ggplot2` pipelines: + ```{r, message = FALSE,fig.width=7} library(dplyr) library(ggplot2) @@ -127,9 +133,7 @@ starwars %>% coord_flip() ``` - - ## Additional Vignettes - - [Speed of glue](https://glue.tidyverse.org/articles/speed.html) - - [Transformers](https://glue.tidyverse.org/articles/transformers.html) +- [Speed of glue](https://glue.tidyverse.org/articles/speed.html) +- [Transformers](https://glue.tidyverse.org/articles/transformers.html) From 1a479e83362e0618856774da09d7ccfaf48cac61 Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Thu, 26 Jan 2023 11:33:22 -0600 Subject: [PATCH 3/4] Remove duplicate contents from README --- README.Rmd | 143 +++------------------------------- README.md | 221 +++++++---------------------------------------------- 2 files changed, 37 insertions(+), 327 deletions(-) diff --git a/README.Rmd b/README.Rmd index 5bb9174..4b2d443 100644 --- a/README.Rmd +++ b/README.Rmd @@ -1,7 +1,5 @@ --- -output: - github_document: - html_preview: false +output: github_document --- @@ -39,111 +37,35 @@ devtools::install_github("tidyverse/glue") ## Usage -##### Variables can be passed directly into strings. -```{r} -library(glue) -name <- "Fred" -glue('My name is {name}.') -``` +`glue()` makes it easy to interpolate data into strings: -##### Long strings are broken by line and concatenated together. ```{r} library(glue) name <- "Fred" -age <- 50 -anniversary <- as.Date("1991-10-12") -glue('My name is {name},', - ' my age next year is {age + 1},', - ' my anniversary is {format(anniversary, "%A, %B %d, %Y")}.') -``` - -##### Named arguments are used to assign temporary variables. -```{r} -glue('My name is {name},', - ' my age next year is {age + 1},', - ' my anniversary is {format(anniversary, "%A, %B %d, %Y")}.', - name = "Joe", - age = 40, - anniversary = as.Date("2001-10-12")) -``` - -##### `glue_data()` is useful with [magrittr](https://cran.r-project.org/package=magrittr) pipes. -```{r} -`%>%` <- magrittr::`%>%` -head(mtcars) %>% glue_data("{rownames(.)} has {hp} hp") -``` - -##### Or within dplyr pipelines -```{r, message = FALSE} -library(dplyr) -head(iris) %>% - mutate(description = glue("This {Species} has a petal length of {Petal.Length}")) -``` - -##### Leading whitespace and blank lines from the first and last lines are automatically trimmed. -This lets you indent the strings naturally in code. -```{r} -glue(" - A formatted string - Can have multiple lines - with additional indention preserved - ") -``` - -##### An additional newline can be used if you want a leading or trailing newline. -```{r} -glue(" - - leading or trailing newlines can be added explicitly - - ") -``` - -##### `\\` at the end of a line continues it without a new line. -```{r} -glue(" - A formatted string \\ - can also be on a \\ - single line - ") -``` +glue('My name is {name}.') -##### A literal brace is inserted by using doubled braces. -```{r} +# A literal brace is inserted by using doubled braces. name <- "Fred" glue("My name is {name}, not {{name}}.") ``` -##### Alternative delimiters can be specified with `.open` and `.close`. -```{r} -one <- "1" -glue("The value of $e^{2\\pi i}$ is $<>$.", .open = "<<", .close = ">>") -``` +`glue_data()` works well with pipes: -##### All valid R code works in expressions, including braces and escaping. -Backslashes do need to be doubled just like in all R strings. ```{r} - `foo}\`` <- "foo" -glue("{ - { - '}\\'' # { and } in comments, single quotes - \"}\\\"\" # or double quotes are ignored - `foo}\\`` # as are { in backticks - } - }") +mtcars$model <- rownames(mtcars) +mtcars |> head() |> glue_data("{model} has {hp} hp") ``` -##### `glue_sql()` makes constructing SQL statements safe and easy +`glue_sql()` makes constructing SQL statements safe and easy. Use backticks to quote identifiers, normal strings and numbers are quoted appropriately for your backend. ```{r} -library(glue) - con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:") colnames(iris) <- gsub("[.]", "_", tolower(colnames(iris))) DBI::dbWriteTable(con, "iris", iris) + var <- "sepal_width" tbl <- "iris" num <- 2 @@ -154,54 +76,9 @@ glue_sql(" WHERE {`tbl`}.sepal_length > {num} AND {`tbl`}.species = {val} ", .con = con) - -# `glue_sql()` can be used in conjunction with parameterized queries using -# `DBI::dbBind()` to provide protection for SQL Injection attacks - sql <- glue_sql(" - SELECT {`var`} - FROM {`tbl`} - WHERE {`tbl`}.sepal_length > ? - ", .con = con) -query <- DBI::dbSendQuery(con, sql) -DBI::dbBind(query, list(num)) -DBI::dbFetch(query, n = 4) -DBI::dbClearResult(query) - -# `glue_sql()` can be used to build up more complex queries with -# interchangeable sub queries. It returns `DBI::SQL()` objects which are -# properly protected from quoting. -sub_query <- glue_sql(" - SELECT * - FROM {`tbl`} - ", .con = con) - -glue_sql(" - SELECT s.{`var`} - FROM ({sub_query}) AS s - ", .con = con) - -# If you want to input multiple values for use in SQL IN statements put `*` -# at the end of the value and the values will be collapsed and quoted appropriately. -glue_sql("SELECT * FROM {`tbl`} WHERE sepal_length IN ({vals*})", - vals = 1, .con = con) - -glue_sql("SELECT * FROM {`tbl`} WHERE sepal_length IN ({vals*})", - vals = 1:5, .con = con) - -glue_sql("SELECT * FROM {`tbl`} WHERE species IN ({vals*})", - vals = "setosa", .con = con) - -glue_sql("SELECT * FROM {`tbl`} WHERE species IN ({vals*})", - vals = c("setosa", "versicolor"), .con = con) ``` -##### Optionally combine strings with `+` - -```{r} -x <- 1 -y <- 3 -glue("x + y") + " = {x + y}" -``` +Learn more in `vignette("glue")`. # Other implementations diff --git a/README.md b/README.md index b3494cb..5df5b21 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ # glue -[![CRAN\_Status\_Badge](https://www.r-pkg.org/badges/version/glue)](https://cran.r-project.org/package=glue) +[![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/glue)](https://cran.r-project.org/package=glue) [![Travis-CI Build Status](https://travis-ci.org/tidyverse/glue.svg?branch=master)](https://travis-ci.org/tidyverse/glue) [![Coverage @@ -30,46 +30,26 @@ devtools::install_github("tidyverse/glue") ## Usage -##### Variables can be passed directly into strings. +`glue()` makes it easy to interpolate data into strings: ``` r library(glue) + name <- "Fred" glue('My name is {name}.') #> My name is Fred. -``` - -##### Long strings are broken by line and concatenated together. - -``` r -library(glue) +# A literal brace is inserted by using doubled braces. name <- "Fred" -age <- 50 -anniversary <- as.Date("1991-10-12") -glue('My name is {name},', - ' my age next year is {age + 1},', - ' my anniversary is {format(anniversary, "%A, %B %d, %Y")}.') -#> My name is Fred, my age next year is 51, my anniversary is Saturday, October 12, 1991. -``` - -##### Named arguments are used to assign temporary variables. - -``` r -glue('My name is {name},', - ' my age next year is {age + 1},', - ' my anniversary is {format(anniversary, "%A, %B %d, %Y")}.', - name = "Joe", - age = 40, - anniversary = as.Date("2001-10-12")) -#> My name is Joe, my age next year is 41, my anniversary is Friday, October 12, 2001. +glue("My name is {name}, not {{name}}.") +#> My name is Fred, not {name}. ``` -##### `glue_data()` is useful with [magrittr](https://cran.r-project.org/package=magrittr) pipes. +`glue_data()` works well with pipes: ``` r -`%>%` <- magrittr::`%>%` -head(mtcars) %>% glue_data("{rownames(.)} has {hp} hp") +mtcars$model <- rownames(mtcars) +mtcars |> head() |> glue_data("{model} has {hp} hp") #> Mazda RX4 has 110 hp #> Mazda RX4 Wag has 110 hp #> Datsun 710 has 93 hp @@ -78,109 +58,15 @@ head(mtcars) %>% glue_data("{rownames(.)} has {hp} hp") #> Valiant has 105 hp ``` -##### Or within dplyr pipelines - -``` r -library(dplyr) -head(iris) %>% - mutate(description = glue("This {Species} has a petal length of {Petal.Length}")) -#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species -#> 1 5.1 3.5 1.4 0.2 setosa -#> 2 4.9 3.0 1.4 0.2 setosa -#> 3 4.7 3.2 1.3 0.2 setosa -#> 4 4.6 3.1 1.5 0.2 setosa -#> 5 5.0 3.6 1.4 0.2 setosa -#> 6 5.4 3.9 1.7 0.4 setosa -#> description -#> 1 This setosa has a petal length of 1.4 -#> 2 This setosa has a petal length of 1.4 -#> 3 This setosa has a petal length of 1.3 -#> 4 This setosa has a petal length of 1.5 -#> 5 This setosa has a petal length of 1.4 -#> 6 This setosa has a petal length of 1.7 -``` - -##### Leading whitespace and blank lines from the first and last lines are automatically trimmed. - -This lets you indent the strings naturally in code. - -``` r -glue(" - A formatted string - Can have multiple lines - with additional indention preserved - ") -#> A formatted string -#> Can have multiple lines -#> with additional indention preserved -``` - -##### An additional newline can be used if you want a leading or trailing newline. - -``` r -glue(" - - leading or trailing newlines can be added explicitly - - ") -#> -#> leading or trailing newlines can be added explicitly -``` - -##### `\\` at the end of a line continues it without a new line. - -``` r -glue(" - A formatted string \\ - can also be on a \\ - single line - ") -#> A formatted string can also be on a single line -``` - -##### A literal brace is inserted by using doubled braces. - -``` r -name <- "Fred" -glue("My name is {name}, not {{name}}.") -#> My name is Fred, not {name}. -``` - -##### Alternative delimiters can be specified with `.open` and `.close`. - -``` r -one <- "1" -glue("The value of $e^{2\\pi i}$ is $<>$.", .open = "<<", .close = ">>") -#> The value of $e^{2\pi i}$ is $1$. -``` - -##### All valid R code works in expressions, including braces and escaping. - -Backslashes do need to be doubled just like in all R strings. +`glue_sql()` makes constructing SQL statements safe and easy. Use +backticks to quote identifiers, normal strings and numbers are quoted +appropriately for your backend. ``` r - `foo}\`` <- "foo" -glue("{ - { - '}\\'' # { and } in comments, single quotes - \"}\\\"\" # or double quotes are ignored - `foo}\\`` # as are { in backticks - } - }") -#> foo -``` - -##### `glue_sql()` makes constructing SQL statements safe and easy - -Use backticks to quote identifiers, normal strings and numbers are -quoted appropriately for your backend. - -``` r -library(glue) - con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:") colnames(iris) <- gsub("[.]", "_", tolower(colnames(iris))) DBI::dbWriteTable(con, "iris", iris) + var <- "sepal_width" tbl <- "iris" num <- 2 @@ -195,82 +81,29 @@ glue_sql(" #> FROM `iris` #> WHERE `iris`.sepal_length > 2 #> AND `iris`.species = 'setosa' - -# `glue_sql()` can be used in conjunction with parameterized queries using -# `DBI::dbBind()` to provide protection for SQL Injection attacks - sql <- glue_sql(" - SELECT {`var`} - FROM {`tbl`} - WHERE {`tbl`}.sepal_length > ? - ", .con = con) -query <- DBI::dbSendQuery(con, sql) -DBI::dbBind(query, list(num)) -DBI::dbFetch(query, n = 4) -#> sepal_width -#> 1 3.5 -#> 2 3.0 -#> 3 3.2 -#> 4 3.1 -DBI::dbClearResult(query) - -# `glue_sql()` can be used to build up more complex queries with -# interchangeable sub queries. It returns `DBI::SQL()` objects which are -# properly protected from quoting. -sub_query <- glue_sql(" - SELECT * - FROM {`tbl`} - ", .con = con) - -glue_sql(" - SELECT s.{`var`} - FROM ({sub_query}) AS s - ", .con = con) -#> SELECT s.`sepal_width` -#> FROM (SELECT * -#> FROM `iris`) AS s - -# If you want to input multiple values for use in SQL IN statements put `*` -# at the end of the value and the values will be collapsed and quoted appropriately. -glue_sql("SELECT * FROM {`tbl`} WHERE sepal_length IN ({vals*})", - vals = 1, .con = con) -#> SELECT * FROM `iris` WHERE sepal_length IN (1) - -glue_sql("SELECT * FROM {`tbl`} WHERE sepal_length IN ({vals*})", - vals = 1:5, .con = con) -#> SELECT * FROM `iris` WHERE sepal_length IN (1, 2, 3, 4, 5) - -glue_sql("SELECT * FROM {`tbl`} WHERE species IN ({vals*})", - vals = "setosa", .con = con) -#> SELECT * FROM `iris` WHERE species IN ('setosa') - -glue_sql("SELECT * FROM {`tbl`} WHERE species IN ({vals*})", - vals = c("setosa", "versicolor"), .con = con) -#> SELECT * FROM `iris` WHERE species IN ('setosa', 'versicolor') ``` -##### Optionally combine strings with `+` - -``` r -x <- 1 -y <- 3 -glue("x + y") + " = {x + y}" -#> x + y = 4 -``` +Learn more in `vignette("glue")`. # Other implementations Some other implementations of string interpolation in R (although not -using identical - syntax). +using identical syntax). - - [stringr::str\_interp](http://stringr.tidyverse.org/reference/str_interp.html) - - [pystr::pystr\_format](https://cran.r-project.org/package=pystr) - - [R.utils::gstring](https://cran.r-project.org/package=R.utils) - - [rprintf](https://cran.r-project.org/package=rprintf) +- [stringr::str_interp](http://stringr.tidyverse.org/reference/str_interp.html) +- [pystr::pystr_format](https://cran.r-project.org/package=pystr) +- [R.utils::gstring](https://cran.r-project.org/package=R.utils) +- [rprintf](https://cran.r-project.org/package=rprintf) String templating is closely related to string interpolation, although not exactly the same concept. Some packages implementing string templating in R include. - - [whisker](https://cran.r-project.org/package=whisker) - - [brew](https://cran.r-project.org/package=brew) +- [whisker](https://cran.r-project.org/package=whisker) +- [brew](https://cran.r-project.org/package=brew) + +## Code of Conduct + +Please note that the glue project is released with a [Contributor Code +of Conduct](https://glue.tidyverse.org/CODE_OF_CONDUCT.html). By +contributing to this project, you agree to abide by its terms. From 3f220492261feb40b1080ecfa63081a443918aec Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Thu, 26 Jan 2023 11:42:21 -0600 Subject: [PATCH 4/4] More details in vignette --- vignettes/glue.Rmd | 147 +++++++++++++++++++++++++-------------------- 1 file changed, 83 insertions(+), 64 deletions(-) diff --git a/vignettes/glue.Rmd b/vignettes/glue.Rmd index b065804..af65212 100644 --- a/vignettes/glue.Rmd +++ b/vignettes/glue.Rmd @@ -8,58 +8,69 @@ vignette: > --- ```{r, include = FALSE} -knitr::opts_chunk$set(collapse = TRUE, - comment = "#>", - messages = FALSE, - warning = FALSE) - -library(glue) +knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` The `glue` package contains functions for glueing together character strings and R code. -```{r eval = FALSE} -# Install the released version of the glue package from CRAN: -install.packages("glue") - -# Load the glue package +```{r} library(glue) ``` -## Glueing character strings +## Gluing and interpolating `glue()` can be used to glue together character strings, such as text: ```{r} -glue("glueing", "some", "text", "together") +glue("glueing ", "some ", "text ", "together") ``` -The default for `glue()` is glueing with *no* separator--- you can provide a separator with the `.sep` argument: +But it's real power comes with `{}`: anything inside of `{}` will be evaluated and pasted into the string. +This makes it easy to interpolate variables: ```{r} -glue("glueing", "some", "text", "together", .sep = " ") -glue("glueing", "some", "text", "together", .sep = ".") +name <- "glue" +glue('We are learning how to use the {name} R package.') ``` -You can optionally combine strings with `+`: +And more complex functions: ```{r} -glue("glueing") + " some" + " text" + " together" +release_date <- as.Date("2017-06-13") +glue('The first version of the glue package was released on a {format(release_date, "%A")}.') ``` -## Glueing & formatting +All valid R code works in expressions, including braces and escaping. +Backslashes do need to be doubled just like in all R strings. +```{r} +`foo}\`` <- "foo" +glue("{ + { + '}\\'' # { and } in comments, single quotes + \"}\\\"\" # or double quotes are ignored + `foo}\\`` # as are { in backticks + } + }") +``` + +## Long lines + +Glue comes with a number of features that make it easier to use when work with large quantities of text. Leading whitespace and blank lines from the first and last lines are automatically trimmed with `glue()`, letting you indent the strings naturally in code: ```{r} -glue(" +my_fun <- function() { + glue(" A formatted string Can have multiple lines with additional indention preserved - ") + ") +} +my_fun() ``` -An additional newline can be used if you want a leading or trailing newline. +An add extra newlines can be used if you want a leading or trailing newline: ```{r} glue(" @@ -69,7 +80,7 @@ glue(" ") ``` -`\\` at the end of a line continues it without a new line: +You can use `\\` at the end of a line continues to continue a single line: ```{r} glue(" @@ -79,61 +90,69 @@ glue(" ") ``` -You can add colour to your strings with `glue_col()`: - -```{r} -library(crayon) +## SQL -glue_col("{blue glueing blue text together}") -glue_col("This ", "{red text}", " is not", " {blue blue}") +glue_sql()` makes constructing SQL statements safe and easy +Use backticks to quote identifiers, normal strings and numbers are quoted +appropriately for your backend. +```{r} +con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:") +colnames(iris) <- gsub("[.]", "_", tolower(colnames(iris))) +DBI::dbWriteTable(con, "iris", iris) +var <- "sepal_width" +tbl <- "iris" +num <- 2 +val <- "setosa" +glue_sql(" + SELECT {`var`} + FROM {`tbl`} + WHERE {`tbl`}.sepal_length > {num} + AND {`tbl`}.species = {val} + ", .con = con) ``` -## Glueing character strings *with* R code - -Glue evaluates R code provided in curly braces and glues the result together with character strings. - -Variables can be passed directly into strings: +`glue_sql()` can be used in conjunction with parameterized queries using `DBI::dbBind()` to provide protection for SQL Injection attacks ```{r} -name <- "glue" -glue('We are learning how to use the {name} R package.') +sql <- glue_sql(" + SELECT {`var`} + FROM {`tbl`} + WHERE {`tbl`}.sepal_length > ? +", .con = con) +query <- DBI::dbSendQuery(con, sql) +DBI::dbBind(query, list(num)) +DBI::dbFetch(query, n = 4) +DBI::dbClearResult(query) ``` -R expressions can be passed into strings: +`glue_sql()` can be used to build up more complex queries with + interchangeable sub queries. It returns `DBI::SQL()` objects which are properly protected from quoting. ```{r} -release_date <- as.Date("2017-06-13") -glue('The first version of the glue package was released on a {format(release_date, "%A")}.') +sub_query <- glue_sql(" + SELECT * + FROM {`tbl`} + ", .con = con) + +glue_sql(" + SELECT s.{`var`} + FROM ({sub_query}) AS s + ", .con = con) ``` -## Glue with a data frame +If you want to input multiple values for use in SQL IN statements put `*` at the end of the value and the values will be collapsed and quoted appropriately. -`glue_data()` can be used to work with a list or data frame: - -```{r message=FALSE} -library(dplyr) - -glue_data(head(starwars), "{name} is from the planet {homeworld}.") -``` - -## Glueing with `dplyr` & `ggplot2` +```{r} +glue_sql("SELECT * FROM {`tbl`} WHERE sepal_length IN ({vals*})", + vals = 1, .con = con) -`glue()` can be used with `dplyr` & `ggplot2` pipelines: +glue_sql("SELECT * FROM {`tbl`} WHERE sepal_length IN ({vals*})", + vals = 1:5, .con = con) -```{r, message = FALSE,fig.width=7} -library(dplyr) -library(ggplot2) +glue_sql("SELECT * FROM {`tbl`} WHERE species IN ({vals*})", + vals = "setosa", .con = con) -starwars %>% - mutate(new_x_label = glue("{name} ({species})")) %>% - filter(height > 200) %>% - ggplot(aes(new_x_label, height)) + - geom_col() + - coord_flip() +glue_sql("SELECT * FROM {`tbl`} WHERE species IN ({vals*})", + vals = c("setosa", "versicolor"), .con = con) ``` - -## Additional Vignettes - -- [Speed of glue](https://glue.tidyverse.org/articles/speed.html) -- [Transformers](https://glue.tidyverse.org/articles/transformers.html)