首页 > 解决方案 > 通过 ggplot 中的 str_detect 类添加多条 geom_density 线

问题描述

我希望能够在 ggplot 的密度图上覆盖多条线,以便为被检测为子字符串的多个类绘制距离?

dat<- data.frame(Image = c(1,1,1,2,2,2,3,3,3,4,4,4), 
                 Class = c("A","A:B","A:C","A:D","D:C","B","B:C","A:B","C:D","A:B:C","A:B:C ","A:B:C:D"),
                 Distance = c(1,5,6,2,4,8,9,1,2,3,7,8))

例如,我想在同一图中以单独的行显示包含类“A”或“B”的任何子字符串的距离。我该怎么办?

dat %>% filter(str_detect(Class,"A")) %>% 
  ggplot(aes(Distance))+
    geom_density()
dat %>% filter(str_detect(Class,"B")) %>% 
  ggplot(aes(Distance))+
    geom_density()

标签: rggplot2stringr

解决方案


这可以通过使用多个geom_density层来实现,您将每个密度层传递一个过滤数据集。为了减少代码重复,我的方法使用了一个辅助函数,并lapply通过循环一个包含在图中的模式向量来添加这些密度层:

dat<- data.frame(Image = c(1,1,1,2,2,2,3,3,3,4,4,4), 
                 Class = c("A","A:B","A:C","A:D","D:C","B","B:C","A:B","C:D","A:B:C","A:B:C ","A:B:C:D"),
                 Distance = c(1,5,6,2,4,8,9,1,2,3,7,8))

library(dplyr)
library(stringr)
library(ggplot2)

make_layer <- function(pattern) {
  dat <- dat %>% 
    filter(str_detect(Class, pattern))
  geom_density(data = dat, aes(color = pattern))
}

patterns <- c("A", "B", "A:B:C")

ggplot(mapping = aes(Distance)) +
  lapply(patterns, make_layer)


推荐阅读