I'm trying to use double curly brackets in a function that makes a timeseries plot, and I've hit a wall, despite reading this
CodePudding user response:
The double curly braces work with unquoted variables names. With variables names as character strings, use aes_string
, see also here.
suppressPackageStartupMessages({
library(dplyr)
library(ggplot2)
library(lubridate)
})
#Sample data
test <- tibble(Week = seq(as.Date("2014/09/04"), by = "week", length.out = 8),
Month = ymd(rep('2014-09-01', 4), rep('2014-10-01', 4)),
Week_score = c(2, 3, 4, 6, 5, 7, 8, 9),
Month_score = c(15, NA, NA, NA, 29, NA, NA, NA))
#My function
make_time_plot <- function(data, time_period = c("Week", "Month")) {
time_period <- match.arg(time_period)
time_period_score <- paste0(time_period, "_score")
data %>%
ggplot(aes_string(x = time_period, y = time_period_score))
geom_line()
}
#make_time_plot(data = test, time_period = "Month")
make_time_plot(data = test, time_period = "Week")
Created on 2022-04-02 by the reprex package (v2.0.1)
CodePudding user response:
There are several things going on here. {{}}
work on unquoted variables, and cannot be mixed and matched with strings.
For example: when you write mtcars %>% select(hp)
, you don't need to write "hp"
. This is due to "data masking", a process which makes R understand that hp
is a variable in mtcars
, and not a variable in your environment. It´t the process that makes this code work:
# Defining an env-variable
cyl <- 1000
# Referring to a data-variable
dplyr::summarise(mtcars, mean(cyl))
#> mean(cyl)
#> 1 6.1875
Created on 2022-04-02 by the reprex package (v2.0.1)
How to fix your function
There are easier ways to fix your function, without using {{}}
, but if you want to see how to do it with {{}}
I've included an example here.
make_time_plot <- function(data, time_period) {
time_period_score <- paste0(rlang::as_name(enquo(time_period)), "_score")
data %>%
ggplot(
aes(
x = {{time_period}},
y = .data[[time_period_score]]
)
)
geom_line()
}
make_time_plot(data = test, time_period = Week)
Created on 2022-04-02 by the reprex package (v2.0.1)
I've changed the following:
- Since you want to paste a string to
time_period
, andtime_period
is a unquoted variable, you need to make it into a string usingrlang::as_name(enquo(time_period))
. - Since
time_period_score
is a string, you need to supply it toaes()
as a string. Sincetime_period
is not a string, you cannot useaes_string()
, so instead I use the.data
pronoun with.data[[time_period_score]]
.
You can find more information about {{}}
here.