【问题标题】:Overlay normal desnity curves in R using ggplot使用 ggplot 在 R 中叠加正态密度曲线
【发布时间】:2015-09-16 04:36:26
【问题描述】:

我正在尝试使用 ggplot 在 R 中的堆叠直方图上叠加正态密度曲线。 bsa 是数值测量值,它们被记录为两组,治疗组和对照组。

我为两组创建了堆叠直方图。我收到一个关于映射需要是未评估映射列表的错误 stat_function。

任何关于如何做到这一点的建议将不胜感激。

ggplot(data=bsa, aes(x=bsa)) +geom_histogram(colours(distinct=TRUE)) + facet_grid(group~.) +
  stat_function(dnorm(x, mean(bsa$bsa),sd(bsa$bsa)))+
  ggtitle("Histogram of BSA amounts by group")  

【问题讨论】:

  • 欢迎 @A M。为了增加获得答案的可能性,您应该发布一段可重现的代码和确切的错误消息。

标签: r ggplot2


【解决方案1】:

stat_function(...) 与构面一起使用很棘手。 stat_function(...) 接受一个参数args=...,它需要是函数的额外参数的命名列表(所以在你的情况下,meansd)。问题是这些不能出现在aes(...) 中,因此您必须手动添加曲线。这是一个例子。

set.seed(1)   # for reproducible example
df <- data.frame(bsa=rnorm(200, mean=rep(c(1,4),each=100)), 
                 group=rep(c("test","control"),each=100))
# calculate mean and sd by group
stats <- aggregate(bsa~group, df, function(x) c(mean=mean(x), sd=sd(x)))
stats <- data.frame(group=stats[,1],stats[,2])

library(ggplot2)
ggplot(df, aes(x=bsa)) +
  geom_histogram(aes(y=..density..,fill=group), color="grey30")+
  with(stats[stats$group=="control",],stat_function(data=df[df$group=="control",],fun=dnorm, args=list(mean=mean, sd=sd)))+
  with(stats[stats$group=="test",],stat_function(data=df[df$group=="test",],fun=dnorm, args=list(mean=mean, sd=sd)))+
  facet_grid(group~.)

这相当难看,所以我通常只计算ggplot 外部的曲线并使用geom_line(...) 添加它们。

x <- with(df, seq(min(bsa), max(bsa), len=100))
dfn <- do.call(rbind,lapply(1:nrow(stats), 
                            function(i) with(stats[i,],data.frame(group, x, y=dnorm(x,mean=mean,sd=sd)))))
ggplot(df, aes(x=bsa)) +
  geom_histogram(aes(y=..density..,fill=group), color="grey30")+
  geom_line(data=dfn, aes(x, y))+
  facet_grid(group~.)

这使ggplot 代码更具可读性,并产生几乎相同的东西。

请注意,如果您想叠加核密度估计,而不是正态曲线,这会容易得多:

ggplot(df, aes(x=bsa)) +
  geom_histogram(aes(y=..density..,fill=group), color="grey30")+
  stat_density(geom="line")+
  facet_grid(group~.)

【讨论】: