If else in ggplot +在geom_vline的字符和数字之间切换值

Posted

技术标签:

【中文标题】If else in ggplot +在geom_vline的字符和数字之间切换值【英文标题】:If else in ggplot + switching values between character and numeric for geom_vline 【发布时间】:2021-06-23 08:01:30 【问题描述】:

我需要在 ggplot 中集成 if else 块,其中取决于 variable_to_switch 的值:

如果值为数字 -> 绘图线 值是文本 -> 不要画线

我以最完整的版本提供我的代码,以考虑与提供的解决方案可能发生的冲突。


#  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


如果variable_to_switch == "Text" 我会有这个错误: Error: Discrete value supplied to continuous scale.

对于variable_to_switch 等于任何数值绘图都有效。

我想在 variable_to_switch 的字符和数值之间切换。所需输出 对于 variable_to_switch == "Text" 的情况:

【问题讨论】:

metrics_test$xintercept 列不是数字,这就是您收到错误的原因。您不能将非数字值作为xintercept 发送给geom_vline()。无论如何,您都无法从该数据集中绘制第 6 行,对吧? 是的,我知道我无法发送非数字值。但这就是有时它是非数字的。与此同时,我只为 ifelse 块使用了 2 个不同的代码。这是多余的,但有效。我想知道这种情况是否有更优雅的解决方案。 【参考方案1】:

如评论中所述,主要问题是数据框metrics_test 中的xintercept 列包含数字和文本。数据框列只能包含一种变量类型,并且文本不能是数字,因此该列将始终为chr 类型,而不是num 类型。然后将此列分配给 geom_vline() 调用中的 xintercept 美学,这是错误消息的来源。

如果您提供的该数据框的子集不包含 metrics_test$xintercept 中的文本值,则可以通过强制列为数字类型来解决此问题 - 只要该列不再包含任何文本。在您的示例代码中,如果将代码的第一部分替换为以下内容,则它可以正常工作:

# 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..

【讨论】:

以上是关于If else in ggplot +在geom_vline的字符和数字之间切换值的主要内容,如果未能解决你的问题,请参考以下文章

那么如何处理 if-else in promise 呢?

Python_基础_Day_2

java_if_else__

java__if_else__的注释

python中if else流程判断

java__if_else 的练习