I've written a function in R to produce a graph from a given data frame:
my_graph <- function (df, scale_fac)
{
row_count = nrow(df)
df %>% mutate(star_sign = as.numeric(factor(star_sign, levels = lvls))) %>%
ggplot(aes(star_sign)) +
geom_line(aes(y = mean), color = "red") +
geom_line(aes(y = min), color = "blue") +
geom_line(aes(y = max), color = "green") +
geom_col(aes(y = scale_fac * exposure), width = 0.5, fill = "blue") +
scale_y_continuous("Linear Predictor", sec.axis = sec_axis(~ ./scale_fac , name = "Exposure")) +
scale_x_continuous("Star Sign", breaks = c(1:row_count), labels = df$lvls) +
theme_bw()
}
df <- data.frame(star_sign = c("Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo", "Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces"),
exposure = c(50, 70, 60, 40, 45, 78, 42, 22, 28, 49, 50, 31),
mean = c(1.1, 1.2, 1.4, 1.3, 1.8, 1.6, 1.4, 1.3, 1.2, 1.1, 1.5, 1.3))
df$min <- 0.95 * df$mean
df$max <- 1.05 * df$mean
df$lvls = c("Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo", "Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces")
my_graph(df, 1/150)
However there are some hard coded bits in the ggplot()
statement such as exposure
, mean
, min
, max
which I'd like to get rid of by passing the names of the fields as additional function parameters, but I can't work out how to do it. I first tried using the [[]]
notation, but it didn't work. I then discovered that there's a !!
notation in tidyverse
but to test this I modified my function definition to include a mean_name
parameter and then referred to !!mean_name
instead of mean
inside the ggplot()
statement:
my_graph_2 <- function (df, mean_name, scale_fac)
{
df %>% mutate(star_sign = as.numeric(factor(star_sign, levels = df$lvls))) %>%
ggplot(aes(star_sign)) +
geom_line(aes(y = !!mean_name), color = "red") +
geom_line(aes(y = min), color = "blue") +
geom_line(aes(y = max), color = "green") +
geom_col(aes(y = scale_fac * exposure), width = 0.5, fill = "blue") +
scale_y_continuous("Linear Predictor", sec.axis = sec_axis(~ ./scale_fac , name = "Exposure")) +
scale_x_continuous("Star Sign", breaks = c(1:row_count), labels = df$lvls) +
theme_bw()
}
df <- data.frame(star_sign = c("Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo", "Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces"),
exposure = c(50, 70, 60, 40, 45, 78, 42, 22, 28, 49, 50, 31),
mean = c(1.1, 1.2, 1.4, 1.3, 1.8, 1.6, 1.4, 1.3, 1.2, 1.1, 1.5, 1.3))
df$min <- 0.95 * df$mean
df$max <- 1.05 * df$mean
df$lvls = c("Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo", "Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces")
my_graph_2(df, "mean", 1/150)
When I run this I see:
Error: Discrete value supplied to continuous scale
which I don't understand. Can anyone help please?
Update: if I use aes_string()
it seems to work. Revised function definition:
my_graph <- function (df, mean_name, scale_fac)
{
row_count = nrow(df)
df %>% mutate(star_sign = as.numeric(factor(star_sign, levels = lvls))) %>%
ggplot(aes(star_sign)) +
#geom_line(aes(y = mean), color = "red") +
geom_line(aes_string(y = mean_name), color = "red") +
geom_line(aes(y = min), color = "blue") +
geom_line(aes(y = max), color = "green") +
geom_col(aes(y = scale_fac * exposure), width = 0.5, fill = "blue") +
scale_y_continuous("Linear Predictor", sec.axis = sec_axis(~ ./scale_fac , name = "Exposure")) +
scale_x_continuous("Star Sign", breaks = c(1:row_count), labels = df$lvls) +
theme_bw()
}