R语言 ggplot:删除图例中的NA因子水平

14ifxucb  于 2023-03-27  发布在  其他
关注(0)|答案(4)|浏览(241)

如何从图例中省略因子的NA水平?

nycflights13数据库中,我创建了一个名为tot_delay的新连续变量,然后创建了一个名为delay_class的因子,该因子具有4个水平。当我绘图时,我过滤掉了NA值,但它们仍然显示在图例中。下面是我的代码:

library(nycflights13); library(ggplot2)

flights$tot_delay = flights$dep_delay + flights$arr_delay
flights$delay_class <- cut(flights$tot_delay,                                   
                           c(min(flights$tot_delay, na.rm = TRUE), 0, 20 , 120,
                             max(flights$tot_delay, na.rm = TRUE)),   
                           labels = c("none", "short","medium","long"))     

filter(flights, !is.na(tot_delay)) %>% 
  ggplot() +
  geom_bar(mapping = aes(x = carrier, fill = delay_class), position = "fill")
af7jpaap

af7jpaap1#

父级示例并不能很好地说明问题(当然,应该跟踪并消除意外的NA值),但这是Google上的顶级结果,因此应该注意的是,scale_XXX_XXX中现在有一个选项,可以通过设置na.translate = F来防止NA级别显示在图例中。例如:

# default    
ggplot(data = data.frame(x = c(1,2,NA), y = c(1,1,NA), a = c("A","B",NA)),
           aes(x, y, colour = a)) + geom_point(size = 4)

# with na.translate = F    
ggplot(data = data.frame(x = c(1,2,NA), y = c(1,1,NA), a = c("A","B",NA)),
           aes(x, y, colour = a)) + geom_point(size = 4) + 
           scale_colour_discrete(na.translate = F)

这在ggplot2 3.1.0中有效。

j1dl9f46

j1dl9f462#

你有一个数据点,其中delay_classNA,但tot_delay不是。这个点没有被过滤器捕获。将代码更改为:

filter(flights, !is.na(delay_class)) %>% 
  ggplot() +
  geom_bar(mapping = aes(x = carrier, fill = delay_class), position = "fill")

就能做到

或者,如果您绝对必须有额外的点,您可以覆盖fill图例,如下所示:

filter(flights, !is.na(tot_delay)) %>% 
  ggplot() +
  geom_bar(mapping = aes(x = carrier, fill = delay_class), position = "fill") +
  scale_fill_manual( breaks = c("none","short","medium","long"),
                    values = scales::hue_pal()(4) )

**更新:**正如@gatsky的回答所指出的,所有离散尺度都包含na.translate参数。该功能实际上从ggplot 2.2.0开始就存在了;我只是在发布我的答案时没有意识到它。为了完整起见,它在原始问题中的用法如下:

filter(flights, !is.na(tot_delay)) %>% 
  ggplot() +
  geom_bar(mapping = aes(x = carrier, fill = delay_class), position = "fill") +
  scale_fill_discrete(na.translate=FALSE)
xesrikrc

xesrikrc3#

我喜欢上面@阿尔特姆的方法,也就是说,找出df中存在NA的原因。然而,有时候你“知道”存在NA,而你只是想排除它们。在这种情况下,简单地使用'na.omit'就可以了:

na.omit(flights) %>% ggplot() +
geom_bar(mapping = aes(x = carrier, fill = delay_class), position = "fill")
watbbzwu

watbbzwu4#

如果你知道NA的颜色是grey50,你也可以使用scale_color_manualscale_fill_manual。所以你可以指定values,只指定breaks来绘制你想要绘制的颜色。下面是一些可重复的代码(data @gatsky):

df = data.frame(x = c(1,2,NA), y = c(1,1,NA), a = c("A","B",NA))
library(ggplot2)
ggplot(data = df, aes(x, y, colour = a)) + 
  geom_point(size = 4) +
  scale_color_manual(values = c("red", "blue", "grey50"),
                     breaks = c("A", "B"))

正如您所看到的,通过指定values中的所有颜色,只有A和B的breaks将从图例中删除NA。
如果你想在图例中使用标准颜色,你可以使用scales包中的hue_pal函数,如下所示:

df = data.frame(x = c(1,2,NA), y = c(1,1,NA), a = c("A","B",NA))
library(ggplot2)
library(scales)
ggplot(data = df, aes(x, y, colour = a)) + 
  geom_point(size = 4) +
  scale_color_manual(values = c(hue_pal()(2), "grey50"),
                     breaks = c("A", "B"))

最后,使用OP中的数据,以scale_fill_manual为例,如下所示:

library(nycflights13) 
library(ggplot2)
library(dplyr)
library(scales)

filter(flights, !is.na(tot_delay)) %>% 
  ggplot() +
  geom_bar(mapping = aes(x = carrier, fill = delay_class), position = "fill") +
  scale_fill_manual(values = c(hue_pal()(4), "grey50"),
                    breaks = c("none", "short", 'medium', 'long'))

创建于2023-03-25带有reprex v2.0.2

相关问题