rif-statementggplot2geom-vline

If else in ggplot + switching values between character and numeric for geom_vline


I need to integrate if else block in ggplot, where depending on value for variable_to_switch it will:

I provide my code in the most complete version to take in account possible conflicts with provided solution.


#  Creating Data ----

obs_number <- 500
mean <- 2
median <- 3
dens_mode <- 2
variable_to_switch <- "Text"
dlt_standard_mean <- 2
cut_off <- 12
max_dlt <- 15

metrics_test <- data.frame(xintercept = c(obs_number,cut_off,max_dlt, 0, mean, median, dens_mode,variable_to_switch, dlt_standard_mean ),
                      label = c("Label 1",
                                "Label 2",
                                "Label 3",
                                "", 
                                "Label 4",
                                "Label 5",
                                "Label 6",
                                "Label 7",
                                "Label 8"))


mean_by_batch_route <- c(rep(1,81), rep(2,252), rep(3,170), rep(4,41))
Label <- c(rep('Label',544))

data_to_plot_test <- data.frame(cbind(Label,mean_by_batch_route))
data_to_plot_test$mean_by_batch_route <- as.numeric(data_to_plot_test$mean_by_batch_route)

# Plotting ---

x_data <- 4

histo_density_plot <- ggplot(data_to_plot_test, aes(x = mean_by_batch_route)) +
  
  geom_histogram(aes(y = ..density..), binwidth = 1, colour= "black", fill = "white") +
  geom_density(adjust = 1.75, aes(y=..density..), fill="blue", alpha = .25)

if(variable_to_switch == "Text"){
  
  histo_density_plot <- histo_density_plot +
    
    geom_vline(aes(xintercept = xintercept, color = label),
               data = metrics_test[c(6,7,9), ], linetype = "dashed", size = 0.5, alpha = 1,
               key_glyph = draw_key_text) +
    
    
    
    scale_color_manual(
      name= "Values",
      limits = metrics_test$label,
      values = c("navyblue","darkcyan", "cyan4", "white", "black", "chartreuse4", "purple","darkgoldenrod3", "red"),
      guide = guide_legend(override.aes = list(label = metrics_test$xintercept, 
                                               size = 3)))
  
} else {
  
  histo_density_plot <- histo_density_plot +
    geom_vline(aes(xintercept = xintercept, color = label),
               data = metrics_test[6:nrow(metrics_test), ], linetype = "dashed", size = 0.5, alpha = 1,
               key_glyph = draw_key_text) +
    
    
    
    scale_color_manual(
      name= "Values",
      limits = metrics_test$label,
      values = c("navyblue","darkcyan", "cyan4", "white", "black", "chartreuse4", "purple","darkgoldenrod3", "red"),
      guide = guide_legend(override.aes = list(label = metrics_test$xintercept, 
                                               size = 3)))
  
  
}

histo_density_plot <- histo_density_plot +
  
  theme(plot.title = element_text(hjust = 0.5, size = 8), 
        axis.title.x = element_text(colour = "darkblue", size=8),
        axis.text.x = element_text(face="plain", color="black", 
                                   size=8, angle=0),
        axis.title.y = element_text(colour = "darkblue", size=8),
        axis.text.y = element_text(face="plain", color="black", 
                                   size=8, angle=0),
        legend.position = c(.80, .70),
        legend.title=element_text(size=8),
        legend.text = element_text(size = 8)
  )+
  
  
  labs(title = relevant_title, y = "Distribution fors DLT values, frequency", x = "DLT for the route: average DLT per batch, days")+
  
  scale_x_continuous(breaks = seq(0, x_data,
                                  ifelse(x_data <= 20, 1,
                                         ifelse((x_data > 20 & x_data < 50), 5, 10))))

histo_density_plot


If variable_to_switch == "Text" I will have this error: Error: Discrete value supplied to continuous scale.

For variable_to_switch equal to any numeric value plot works.

I want to switch between character and numeric value for variable_to_switch.
Desired output for case with variable_to_switch == "Text" : enter image description here


Solution

  • As noted in the comment, the main issue is that the xintercept column in the dataframe metrics_test contains numbers and text. Data frame columns can only contain one variable type, and the text cannot be a number, so this column will always be a chr type, not a num type. You then assign this column to the xintercept aesthetic in the geom_vline() call, which is where the error message is coming from.

    If you are supplying a subset of that dataframe that does not contain a text value in metrics_test$xintercept, you can get around this issue by forcing the column into a numeric type - just as long as the column no longer contains any text. In your example code, if you replace the first part of the code with the following, it works without the error:

    # your code prior to the if/then statement...
    
    if(variable_to_switch == "Text"){
      
      d <- metrics_test[c(6,7,9),]    # temporary data frame
      d$xintercept <- as.numeric(d$xintercept)
      
      histo_density_plot <- histo_density_plot +
        
        geom_vline(aes(xintercept = xintercept, color = label),
                   data = d, linetype = "dashed", size = 0.5, alpha = 1,
                   key_glyph = draw_key_text) +
    
        # the rest of the if then statement and code continues as you have it..
    

    enter image description here