我试图构建一个图,其中我绘制了正态分布的变量,显示了它们在x轴上的平均值和y轴上的标准偏差(SD)。有点像密度图,但不是在y轴上有密度,我想要SD(值)。
我正在使用以下数据,
set.seed(1)
mu1 <- rnorm(10^5, mean = 1, sd = 1)
mu3 <- rnorm(10^5, mean = 3, sd = 2)
两个正态分布的变量。这里是他们的平均值和sd,
# install.packages("tidyverse", dependencies = TRUE)
require(tidyverse)
tibble(mu1, mu3) %>% summarise_all(funs(mean, sd))
#> # A tibble: 1 x 4
#> mu1_mean mu3_mean mu1_sd mu3_sd
#> <dbl> <dbl> <dbl> <dbl>
#> 1 0.9993454 3.000825 0.9982848 1.998234
我已经使用ggplot2和其他tidyverse软件包,以便更接近我想要的内容。我也试过从箱子里复制this function做类似的事情,但是还成功了。
这是我的开始,
tibble(mu1, mu3) %>% gather() %>% ggplot() +
geom_density(aes(x = value, colour = key)) +
labs(x = 'mean', y = 'currently density, but I would like sd')
答案 0 :(得分:7)
平均值和标准偏差是在x刻度上测量的,因此您需要沿x轴绘制它们。 y轴是给定x间隔内的点密度,并且类似于直方图中条的高度。
也许这会给你一些你想要的东西:下面的代码添加了一条横跨每个密度图的标准偏差的水平线,以及用于标记它们在x轴上的位置的下拉线。 sd线位于y值,其中分布的宽度等于标准偏差。如果您愿意,您可以另外(或替代)填充标准差所涵盖的区域。
library(dplyr)
# Densities
n = 2^10
df = data.frame(x = c(density(foo,n=n)$x, density(bar,n=n)$x),
y = c(density(foo,n=n)$y, density(bar,n=n)$y),
group=rep(c("foo","bar"), each=n))
## Mean and SD
msd = melt(data.frame(foo=foo, bar=bar)) %>%
group_by(group=variable) %>% summarise(mean=mean(value), sd=sd(value))
# Find y value (of density) where sd has same width as density
msd$y = unlist(lapply(unique(df$group), function(g) {
d = df[df$group==g,]
d$y[which.min(abs(d$x - (msd$mean[msd$group==g] - msd$sd[msd$group==g])))]
}))
ggplot(df, aes(x=x, y=y, colour=group)) +
geom_line() + labs(x = NULL) +
geom_segment(data=msd, aes(y=y,yend=y, x=mean - sd, xend=mean + sd), lty="21") +
geom_point(data=msd, aes(y=y, x=mean)) +
geom_segment(data=msd, aes(x=mean-sd, xend=mean-sd, y=0, yend=y), alpha=0.5, lty="21") +
geom_segment(data=msd, aes(x=mean+sd, xend=mean+sd, y=0, yend=y), alpha=0.5, lty="21")