I'm learning how to query SQLite dbs from R, and building those queries with glue_sql()
. Below is a simplified example of a sub-query from my workflow. Is there a way I can create s10_wtX
and s20_wtX
without using paste0()
, as in the code below?
library(DBI)
library(dplyr)
library(glue)
# example database
set.seed(1)
ps <- data.frame(plot = rep(1:3, each = 4),
spp = rep(1:3*10, 2),
wtX = rnorm(12, 10, 2) %>% round(1))
con <- dbConnect(RSQLite::SQLite(), "")
dbWriteTable(con, "ps", ps)
# species of interest
our_spp <- c(10, 20)
# for the spp of interest, sum wtX on each plot
sq <- glue_sql(paste0(
'SELECT ps.plot,\n',
paste0('SUM(CASE WHEN ps.spp = ', our_spp,
' THEN (ps.wtX) END) AS s', our_spp,
'_wtX',
collapse = ',\n'), '\n',
' FROM ps
WHERE ps.spp IN ({our_spp*}) -- spp in our sample
GROUP BY ps.plot'),
.con = con)
# the result of the query should look like:
dbGetQuery(con, sq)
plot s10_wtX s20_wtX
1 1 21.9 10.4
2 2 11.0 22.2
3 3 9.4 13.0
In my actual workflow, I have more than two species of interest, so I'd rather not fully write out each line (e.g., SUM(CASE WHEN ps.spp = 10 THEN (ps.wtX) END) AS s10_wtX
).
The OP's original question is
Is there a way I can create s10_wtX and s20_wtX without using paste0(), as in the code below?
If we want to construct only with glue
, use glue_collapse
as well
library(glue)
sq1 <- glue_sql('SELECT ps.plot,', glue_collapse(glue('SUM(CASE WHEN ps.spp = {our_spp} THEN (ps.wtX) END) AS s{our_spp}_wtX'), sep = ",\n"), '\nFROM ps\n WHERE ps.spp IN ({our_spp*}) -- spp in our sample\n GROUP BY ps.plot', .con = con)
dbGetQuery(con, sq1)
plot s10_wtX s20_wtX
1 1 21.9 10.4
2 2 11.0 22.2
3 3 9.4 13.0