2

我正在用高斯混合来近似分布,并且想知道是否有一种简单的方法可以使用 ggplot2 以一种很好的方式自动将整个(一维)数据集的估计内核密度绘制为组件密度的总和:

使用单组分密度绘制的完整数据密度

鉴于以下示例数据,我在 ggplot2 中的方法是手动将子集密度绘制成缩放后的整体密度,如下所示:

#example data
a<-rnorm(1000,0,1) #component 1
b<-rnorm(1000,5,2) #component 2
d<-c(a,b) #overall data 
df<-data.frame(d,id=rep(c(1,2),each=1000)) #add group id

##ggplot2
require(ggplot2)

ggplot(df) +
  geom_density(aes(x=d,y=..scaled..)) +
  geom_density(data=subset(df,id==1), aes(x=d), lty=2) +
  geom_density(data=subset(df,id==2), aes(x=d), lty=4)

ggplot2 绘图

请注意,这不适用于比例尺。当您缩放所有 3 个密度或根本没有密度时,它也不起作用。所以我无法复制上面的情节。

此外,我无法自动生成此图,而无需手动进行子集化。我尝试使用 position = "stacked" 作为 geom_density 中的参数。

我通常每个数据集大约有 5-6 个组件,因此可以手动设置子集。但是,我希望每个组件密度有不同的颜色或线型,它们显示在 ggplot 的图例中,因此手动执行所有子集会大大增加工作量。

有任何想法吗?谢谢!

4

1 回答 1

2

这是一个可能的解决方案,通过在一层中指定aes调用中的每个密度,在第二层中使用没有图例的堆叠密度。position = "identity"

ggplot(df) +
  stat_density(aes(x = d,  linetype = as.factor(id)), position = "stack", geom = "line", show.legend = F, color = "red") +
  stat_density(aes(x = d,  linetype = as.factor(id)), position = "identity", geom = "line")

在此处输入图像描述

请注意,当使用超过两个组时:

  a <- rnorm(1000, 0, 1) 
  b <- rnorm(1000, 5, 2) 
  c <- rnorm(1000, 3, 2)
  d <- rnorm(1000, -2, 1)
  d <- c(a, b, c, d)
  df <- data.frame(d, id = as.factor(rep(c(1, 2, 3, 4), each = 1000))) 

出现每个堆栈的曲线(这是两组示例的问题,但linetype在第一层伪装它 -group改为使用检查):

 gplot(df) +
    stat_density(aes(x = d, group = id), position = "stack", geom = "line", show.legend = F, color = "red") +
    stat_density(aes(x = d, linetype = id), position = "identity", geom = "line")

在此处输入图像描述

一个相对简单的解决方法是添加 alpha 映射并将不需要的曲线手动设置为 0:

  ggplot(df) +
    stat_density(aes(x=d, alpha = id), position = "stack", geom = "line", show.legend = F, color = "red") +
    stat_density(aes(x=d,  linetype = id), position = "identity", geom = "line")+
    scale_alpha_manual(values = c(1,0,0,0))

在此处输入图像描述

于 2017-11-12T12:45:22.960 回答