2010-08-20 180 views
3

我試圖用ggplot2生成一些示例圖形,我選擇的其中一個示例是birthday problem,這裏使用Oscon的Revolution computing presentation中的代碼'借來的'。在ggplot2中添加指數geom_smooth

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

問題是概率遵循邏輯曲線。如果更改生日函數以返回原始成功和失敗,而不是概率,則可以擬合適當的平滑線。現在

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) 
+0

曲線並不是真的邏輯,即使它是S形的。你可以在原始圖 – Aniko 2010-08-20 13:48:30

+0

hm右邊的'scale_y_logit()'看到它。我不確定那時適當的迴歸是什麼,但擁有原始數據仍然可以讓你用'stat_smooth()'符合那條線。 – JoFrhwld 2010-08-20 14:46:27

3

平滑例程不作出反應,爲的x足夠快低值的突然變化(和它沒有辦法知道的prob值被限制在0-1範圍內的方式)。由於您的可變性如此之低,因此快速解決方案是減少在每個點完成平滑的值的範圍。看看這個圖中的紅線:

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