1

I have a piece of code which produces a graph in R. It works, but there's a field name star_sign which is hard coded in the function. I'd like to pass this as an extra function parameter variable_name instead and remove the hard coding.

my_graph <- function (df_name, variable_name)
{
  scale_fac <- 4 * max(df_name$exposure) / max(df_name$max) # rule of thumb - it'll do for now

  row_count = nrow(df_name)

  #problem line here - star_sign appears twice

  df_name <- df_name %>% mutate(star_sign = as.numeric(factor(star_sign, levels = my_levels)))

  df_name %>%
    ggplot(aes_string(x = variable_name)) +
    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 = exposure / scale_fac), width = 0.5, fill = "blue") +
    scale_y_continuous("Linear Predictor", sec.axis = sec_axis(~ .*scale_fac , name = "Exposure")) +
    scale_x_continuous(variable_name, breaks = c(1:row_count), labels = df_name$my_levels) +
    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$my_levels = c("Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo", "Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces")

my_graph(df, "star_sign")

The hard coding is in this line

  df_name <- df_name %>% mutate(star_sign = as.numeric(factor(star_sign, levels = my_levels)))

I've read various SO articles about passing column names to R functions but I'm still a relative beginner with R and I'm really struggling to follow them. Can anyone advise the syntax I need please?

Thank you.

1
  • Why are you changing star_sign? You don't seem to use it later in the function. Commented Jan 27, 2020 at 18:23

1 Answer 1

2

We can convert the string input to symbol and then do the evaluation (!!)

my_graph <- function (df_name, variable_name)
{
  scale_fac <- 4 * max(df_name$exposure) / max(df_name$max) # rule of thumb - it'll do for now

  row_count = nrow(df_name)

  #problem line here - star_sign appears twice

  df_name <- df_name %>% mutate(!! variable_name := as.numeric(factor(!! rlang::sym(variable_name), levels = my_levels)))

  df_name %>%
    ggplot(aes(x = !! rlang::sym(variable_name))) +
    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 = exposure / scale_fac), width = 0.5, fill = "blue") +
    scale_y_continuous("Linear Predictor", sec.axis = sec_axis(~ .*scale_fac , name = "Exposure")) +
    scale_x_continuous(variable_name, breaks = c(1:row_count), 
             labels = df_name$my_levels) +
    theme_bw()
}

-checking

my_graph(df, "star_sign")

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you. This seems to work. Now I'm going to stare at the syntax and see if I can work out what's going on...
@Alan you are passing a. string as input. Inside the function, it is converting to symbol (sym) and then do the evaluation (!!) on the rhs of :=, while on the lhs, the !! can be done on the string itself instead of converting to symbol
thank you - I am most grateful (I’ve spent the whole afternoon trying to fix this 😩

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.