График гауссовой смеси в R с использованием ggplot2
Я аппроксимирую распределение гауссовыми смесями, и мне было интересно, есть ли простой способ автоматически построить расчетную плотность ядра всего (одномерного) набора данных в виде суммы плотностей компонентов, как показано ниже, используя 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)
Обратите внимание, что это не работает в отношении весов. Это также не работает, когда вы масштабируете все 3 плотности или вообще не используете плотность. Поэтому я не смог повторить вышеприведенный сюжет.
Кроме того, я не могу автоматически сгенерировать этот график без необходимости поднабора вручную. Я попытался использовать position = "stacked" в качестве параметра в geom_density.
Обычно у меня есть около 5-6 компонентов на набор данных, поэтому подмножество вручную будет возможно. Однако я хотел бы иметь разные цвета или типы линий для плотности компонентов, которые отображаются в легенде ggplot, поэтому выполнение всех подмножеств вручную значительно увеличит рабочую нагрузку.
Есть идеи? Спасибо!
1 ответ
Вот возможное решение, указав каждую плотность в 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")
Относительно легко исправить это, добавив альфа-отображение и вручную установив его на 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))