将正态曲线和水平箱形图添加到已列表的调查数据中

时间:2012-01-31 21:12:42

标签: r charts ggplot2 survey

我已经在数据框中导入了一些已经制表的调查数据,并且可以使用ggplot制作条形图。

  X                X.1 X.2
3 Less than 1 year       7
4        1-5 years      45
5       6-10 years      84
6      11-15 years     104
7 16 or more years     249

ggplot(responses[3:7,], aes(y=X.2, factor(X))) + geom_bar()

我想在条形图上叠加一条正常曲线,并在下方放置一个水平框和胡须图,但我不确定没有个别观察的正确方法,它应该是可能的...我认为。我试图模拟的示例输出是:http://t.co/yOqRmOj5

我期待着为此学习一个新技巧,如果有的话,或者是否有其他人遇到过它。

3 个答案:

答案 0 :(得分:6)

要保存其他任何必须下载134页PDF的人,请参阅问题中引用的图表示例。

http://coast.gkss.de/staff/storch/pdf/CliSci2008.pdf, page 16

在此示例中,数据来自李克特量表,因此可以外推原始数据,并且至少可以解释正态曲线和箱线图。但是,有些图表中水平刻度是标称值。在这些情况下,正常曲线没有意义。

您的问题是关于序数规模。仅从这些汇总数据中,尝试制作正常曲线是不合理的。您可以将每个条目视为其范围的中心点(0。5年,3年,8年等),但无法合理地为最高组分配值(更糟糕的是,它是您最大的,所以它的贡献并非无关紧要)。您必须拥有原始数据以进行任何合理的近似。

答案 1 :(得分:1)

如果您只想根据自己的数据进行密度估算,那么oldlogspline包中的logspline函数可以将密度估算值与区间删失数据拟合:

mymat <- cbind( c(0,1,5.5,10.5, 15.5), c(1,5.5,10.5, 15.5, Inf) )[rep(1:5, c(7,45,84,104,249)),]

library(logspline)

fit <- oldlogspline(interval=mymat[mymat[,2] < 100,],
    right=mymat[ mymat[,2]>100, 1], lbound=0)
fit2 <- oldlogspline.to.logspline(fit)

hist( mymat[,1]+0.5, breaks=c(0,1,5.5,10.5,15.5,60), main='', xlab='Years')
plot(fit2, add=TRUE, col='blue')

如果您想要正态分布,那么survreg包中的survival函数将适合区间删失数据:

library(survival)

mymat2 <- mymat
mymat2[ mymat2>100 ] <- NA

fit3 <- survreg( Surv(mymat2[,1], mymat2[,2], ,type='interval2') ~ 1, 
    dist='gaussian', control=survreg.control(maxiter=100) )
curve( dnorm(x, coef(fit3), fit3$scale), from=0, to=60, col='green', add=TRUE)

虽然不同的分布可能更合适:

fit4 <- survreg( Surv(mymat2[,1]+.01, mymat2[,2], ,type='interval2') ~ 1,
    dist='weibull', control=survreg.control(maxiter=100) )
curve( dweibull(x, scale=exp(coef(fit4)), shape=1/fit4$scale), 
    from=0, to=60, col='red', add=TRUE)

您还可以使用fitdistr中的MASS来填充离散分布:

library(MASS)
tmpfun <- function(x, size, prob) {
    ifelse(x==0, dnbinom(0,size,prob),
    ifelse(x < 5, pnbinom(5,size,prob)-pnbinom(0,size,prob),
    ifelse(x < 10, pnbinom(10,size,prob)-pnbinom(5,size,prob),
    ifelse(x < 15, pnbinom(15,size,prob)-pnbinom(10,size,prob),
        pnbinom(15,size,prob, lower.tail=FALSE)))))
}

fit5 <- fitdistr( mymat[,1], tmpfun, start=list(size=6, prob=0.28) )
lines(0:60, dnbinom(0:60, fit5$estimate[1], fit5$estimate[2]), 
    type='h', col='orange')

如果你想要一些更多模糊的东西,那么5。5年可能被报告为5年或6年,而且我不知道可能会在某种程度上使用(有一些假设),那么EM算法可用于估计参数(但这要复杂得多,您需要指定实际值如何转化为观测值的假设。)

答案 2 :(得分:0)

可能有更好的方式来查看这些数据。由于它被设计约束为整数值,因此拟合泊松或负二项分布可能更为明智。我认为你应该思考这样一个事实,即你提供的数据中的X值有些随意。似乎没有充分的理由认为3是最低类别的最合适的值。为什么不是1?

然后,当然,您需要解释数据所指的内容。它看起来不是普通的,甚至是泊松分布。它是非常偏斜的,并且在常见的使用中没有很多左倾斜分布(尽管存在无限数量的这种分布。

如果您只是想证明非正常数据甚至忽略了您正在拟合正态分布的特定版本的事实,那么请在绘图中查看此练习:

 barp <- barplot( dat$X.2)
 barp  
# this is what barplot returns and is then used as the x-values for a call to lines.
     [,1]
[1,]  0.7
[2,]  1.9
[3,]  3.1
[4,]  4.3
[5,]  5.5
 lines(barp, 1000*dnorm(seq(3,7), 7,2))