首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >向已制表的测量数据添加法线和水平箱形图

向已制表的测量数据添加法线和水平箱形图
EN

Stack Overflow用户
提问于 2012-02-01 05:12:42
回答 3查看 1.5K关注 0票数 0

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

代码语言:javascript
运行
复制
  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

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

EN

回答 3

Stack Overflow用户

发布于 2012-02-01 05:38:28

为了节省其他必须下载134页PDF的人,这里有一个问题中引用的图表示例。

在本例中,数据来自Likert标度,因此可以外推原始数据,并且正常曲线和箱线图至少是可解释的。但是,有些地块的水平比例是标称的。正常曲线在这些情况下没有意义。

你的问题是关于序数尺度的。仅从这些汇总的数据来看,试图做出正常曲线是不合理的。您可以将每个条目视为位于其范围(0.5年、3年、8年等)的中心点,但无法合理地为最高组分配一个值(更糟糕的是,它是您最大的组,因此其贡献并不是微不足道的)。您必须拥有原始数据才能做出任何合理的近似。

票数 6
EN

Stack Overflow用户

发布于 2012-02-02 01:40:38

如果您只需要基于已有数据的密度估计,那么logspline包中的oldlogspline函数可以将密度估计值拟合到区间删失数据:

代码语言:javascript
运行
复制
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')

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

代码语言:javascript
运行
复制
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)

尽管不同的分布可能更适合:

代码语言:javascript
运行
复制
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)

您还可以在MASS中使用fitdistr拟合离散分布

代码语言:javascript
运行
复制
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算法来估计参数(但这要复杂得多,您需要指定假设如何将实际值转换为观测值)。

票数 1
EN

Stack Overflow用户

发布于 2012-02-01 08:05:37

也许有一种更好的方式来看待这些数据。由于它被设计限制为整数值,也许拟合泊松分布或负二项分布可能更合理。我认为您应该考虑这样一个事实,即您所呈现的数据中的X值有些随意。似乎没有很好的理由认为3是最低类别的最合适的值。为什么不是1?

然后,当然,你需要解释这些数据指的是什么。它看起来根本不是正态分布,甚至不是泊松分布。它是非常左偏的,通常情况下没有太多的左偏分布(尽管有无限数量的可能分布)。

如果你只是想证明这个数据是如何非正态的,甚至忽略了你正在拟合正态分布的一个固定版本的事实,那么看看绘图中的这个练习:

代码语言:javascript
运行
复制
 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))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9087029

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档