use*_*531 2 r tidyverse r-glue
我正在尝试使用其中混合有“单”和“双”glue引号的包创建一个字符串。R
作为代表,请考虑SQL我想要构建的以下类型的查询字符串:
CREATE TABLE fact_final_table AS
(SELECT tab1.id,
AVG(tab2."MV") FILTER (WHERE tab2.record_dt BETWEEN tab1.start_date::date - integer '7'
AND tab1.start_date::date - integer '1') AS "mv_avg_1w",
AVG(tab2."MV") FILTER (WHERE tab2.record_dt BETWEEN tab1.start_date::date - integer '14'
AND tab1.start_date::date - integer '1') AS "mv_avg_2w"
FROM (SELECT id,
start_date,
point
FROM base_tab
WHERE mpfb.start_date::date >= '01-01-2000'::date) AS tab1
LEFT JOIN ghcnd_observations AS tab2
ON (tab2.record_dt BETWEEN (tab1.start_date::date - integer '180')
AND (tab1.start_date::date - integer '1')
AND ST_DWithin(tab1.point, tab2.location, 0.5))
GROUP BY tab1.id);
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它是单引号和双引号的组合,按照上面的字面意思保留它们非常重要。例如,tab2."MV"有双引号,tab1.start_date::date - integer '7' AND tab1.start_date::date - integer '1'有单引号,需要按字面保留。
该字符串也需要使用参数构建。R我在using中尝试了以下操作glue,但无法使其工作。
var1 <- "MV"
var1_lowcase <- "mv"
lag_days <- 180
var_date <- as.Date("2000-01-01")
var_dwithin <- 0.5
glue::glue(
"CREATE TABLE fact_final_table AS
(SELECT tab1.id,
AVG(tab2."{var1}") FILTER (WHERE tab2.record_dt BETWEEN tab1.start_date::date - integer '7'
AND tab1.start_date::date - integer '1') AS "{var1_lowcase}_avg_1w",
AVG(tab2."{var1}") FILTER (WHERE tab2.record_dt BETWEEN tab1.start_date::date - integer '14'
AND tab1.start_date::date - integer '1') AS "{var1_lowcase}_avg_2w"
FROM (SELECT id,
start_date,
point
FROM base_tab
WHERE mpfb.start_date::date >= '{format(var_date, "%d-%m-%Y")}'::date) AS tab1
LEFT JOIN ghcnd_observations AS tab2
ON (tab2.record_dt BETWEEN (tab1.start_date::date - integer '{lag_days}')
AND (tab1.start_date::date - integer '1')
AND ST_DWithin(tab1.point, tab2.location, {var_dwithin}))
GROUP BY tab1.id);")
Run Code Online (Sandbox Code Playgroud)
不幸的是,由于单/双引号在glue::glue(...).
任何人都可以在这里提供帮助,以最小程度地破坏所需的输出字符串吗?我不确定这是否容易实现。我将不胜感激任何其他tidy方法,例如使用stringr,因为我希望这是%>%友好的。我简单地看了一下glue::glue_sql,但不知道如何在这里直接应用它。我很高兴能在这里学习如何在适用的情况下使用它。
因此,我从昨天开始更详细地研究了这一点,并且似乎确实glue具有使单引号和双引号显式显示的函数ieglue::single_quote()和
glue::double_quote()。
与 @ronakshah 的(有用的)响应类似,我管理了以下内容,更明确(为了代码可读性):
var1 <- "MV"
var1_lowcase <- "mv"
lag_days <- 180
var_date <- as.Date("2000-01-01")
var_dwithin <- 0.5
glue::glue(
"CREATE TABLE fact_final_table AS
(SELECT tab1.id,
AVG(tab2.{glue::double_quote(var1)}) FILTER (WHERE tab2.record_dt BETWEEN tab1.start_date::date - integer '7'
AND tab1.start_date::date - integer '1') AS {glue::double_quote(glue::glue({var1_lowcase},'_avg_1w'))},
AVG(tab2.{glue::double_quote(var1)}) FILTER (WHERE tab2.record_dt BETWEEN tab1.start_date::date - integer '14'
AND tab1.start_date::date - integer '1') AS {glue::double_quote(glue::glue({var1_lowcase},'_avg_2w'))}
FROM (SELECT id,
start_date,
point
FROM base_tab
WHERE mpfb.start_date::date >= {glue::single_quote(format(var_date, '%d-%m-%Y'))}::date)
AS tab1
LEFT JOIN ghcnd_observations AS tab2
ON (tab2.record_dt BETWEEN (tab1.start_date::date - integer '{lag_days}')
AND (tab1.start_date::date - integer '1')
AND ST_DWithin(tab1.point, tab2.location, {var_dwithin}))
GROUP BY tab1.id);")
Run Code Online (Sandbox Code Playgroud)
它返回我需要的主字符串。希望这对有类似glue需求的其他人有所帮助。