在ggplot2 / R中添加指数geom_smooth

时间:2010-08-20 10:25:50

标签: r ggplot2

我正在尝试使用ggplot2生成一些示例图形,我选择的一个示例是birthday problem,这里使用的是来自Oscon的革命computing presentation的代码'借来的'。

birthday<-function(n){
    ntests<-1000
    pop<-1:365
    anydup<-function(i){
        any(duplicated(sample(pop,n,replace=TRUE)))
        }
    sum(sapply(seq(ntests), anydup))/ntests
    }

x<-data.frame(x=rep(1:100, each=5)) 
x<-ddply(x, .(x), function(df) {return(data.frame(x=df$x, prob=birthday(df$x)))})
birthdayplot<-ggplot(x, aes(x, prob))+
        geom_point()+geom_smooth()+
        theme_bw()+
        opts(title = "Probability that at least two people share a birthday in a random group")+
        labs(x="Size of Group", y="Probability")

这里我的图形是我所描述的指数,但geom_smooth特别不适合数据。我尝试过黄土方法,但这并没有改变很多东西。谁能建议如何添加更好的光滑?

由于

保罗。

2 个答案:

答案 0 :(得分:3)

平滑例程对x的低值的突然变化没有足够快的反应(并且无法知道prob的值被限制在0-1范围内) 。由于您具有如此低的可变性,因此快速解决方案是减少每个点平滑处理的值的范围。看看这个图中的红线:

birthdayplot + geom_smooth(span=0.1, colour="red")

答案 1 :(得分:2)

问题在于概率遵循逻辑曲线。如果更改生日函数以返回原始成功和失败而不是概率,则可以使用适当的平滑线。

birthday<-function(n){
  ntests<-1000
  pop<-1:365
  anydup<-function(i){
    any(duplicated(sample(pop,n,replace=TRUE)))
  }
  data.frame(Dups = sapply(seq(ntests), anydup) * 1, n = n)
}
x<-ddply(x, .(x),function(df) birthday(df$x))

现在,您必须将这些点添加为摘要,并将逻辑回归指定为平滑类型。

ggplot(x, aes(n, Dups)) +
  stat_summary(fun.y = mean, geom = "point") +
  stat_smooth(method = "glm", family = binomial)