2012-06-27 26 views
8

Làm thế nào tôi có thể chồng lên một phân bố tham số tùy ý trên biểu đồ bằng ggplot?Làm thế nào tôi có thể chồng lên một phân phối tham số tùy ý trên biểu đồ bằng ggplot?

Tôi đã thực hiện một nỗ lực dựa trên một số Quick-R example, nhưng tôi không hiểu yếu tố mở rộng đến từ đâu. Phương pháp này có hợp lý không? Làm thế nào tôi có thể sửa đổi nó để sử dụng ggplot?

Một ví dụ overplot sự phân phối chuẩn và lognormal sử dụng phương pháp này sau:

## Get a log-normalish data set: the number of characters per word in "Alice in Wonderland" 
alice.raw <- readLines(con = "http://www.gutenberg.org/cache/epub/11/pg11.txt", 
         n = -1L, ok = TRUE, warn = TRUE, 
         encoding = "UTF-8") 

alice.long <- paste(alice.raw, collapse=" ") 
alice.long.noboilerplate <- strsplit(alice.long, split="\\*\\*\\*")[[1]][3] 
alice.words <- strsplit(alice.long.noboilerplate, "[[:space:]]+")[[1]] 
alice.nchar <- nchar(alice.words) 
alice.nchar <- alice.nchar[alice.nchar > 0] 

# Now we want to plot both the histogram and then log-normal probability dist 
require(MASS) 
h <- hist(alice.nchar, breaks=1:50, xlab="Characters in word", main="Count") 
xfit <- seq(1, 50, 0.1) 

# Plot a normal curve 
yfit<-dnorm(xfit,mean=mean(alice.nchar),sd=sd(alice.nchar)) 
yfit <- yfit * diff(h$mids[1:2]) * length(alice.nchar) 
lines(xfit, yfit, col="blue", lwd=2) 

# Now plot a log-normal curve 
params <- fitdistr(alice.nchar, densfun="lognormal") 
yfit <- dlnorm(xfit, meanlog=params$estimate[1], sdlog=params$estimate[1]) 
yfit <- yfit * diff(h$mids[1:2]) * length(alice.nchar) 
lines(xfit, yfit, col="red", lwd=2) 

này tạo ra cốt truyện sau: Plot produced by the code above, showing a histogram of word length superimposed with a normal distribution curve and a log-normal distribution curve

Để làm rõ, tôi muốn có đếm trên trục y , thay vì ước tính mật độ.

+0

lưu ý rằng một phân phối chuẩn không có ý nghĩa như tất cả các từ có> 0 chữ cái, và các giá trị là số nguyên rời rạc; bình thường là liên tục. –

+0

Đồng ý - đây là ví dụ về đồ chơi có số liệu tiện dụng. Và một đường cong bình thường có lẽ là không phù hợp. – fmark

Trả lời

11

Có một cái nhìn tại stat_function()

alice.raw <- readLines(con = "http://www.gutenberg.org/cache/epub/11/pg11.txt", 
         n = -1L, ok = TRUE, warn = TRUE, 
         encoding = "UTF-8") 

alice.long <- paste(alice.raw, collapse=" ") 
alice.long.noboilerplate <- strsplit(alice.long, split="\\*\\*\\*")[[1]][3] 
alice.words <- strsplit(alice.long.noboilerplate, "[[:space:]]+")[[1]] 
alice.nchar <- nchar(alice.words) 
alice.nchar <- alice.nchar[alice.nchar > 0] 
dataset <- data.frame(alice.nchar = alice.nchar) 
library(ggplot2) 
ggplot(dataset, aes(x = alice.nchar)) + geom_histogram(aes(y = ..density..)) + 
    stat_function(fun = dnorm, 
    args = c(
     mean = mean(dataset$alice.nchar), 
     sd = sd(dataset$alice.nchar)), 
    colour = "red") 

enter image description here

Nếu bạn muốn có đếm trên trục y như trong ví dụ này, sau đó bạn sẽ cần một chức năng có thể chuyển đổi các mật độ để đếm:

dnorm.count <- function(x, mean = 0, sd = 1, log = FALSE, n = 1, binwidth = 1){ 
    n * binwidth * dnorm(x = x, mean = mean, sd = sd, log = log) 
} 

ggplot(dataset, aes(x = alice.nchar)) + geom_histogram(binwidth=1.6) + 
    stat_function(fun = dnorm.count, 
       args = c(
        mean = mean(dataset$alice.nchar), 
        sd = sd(dataset$alice.nchar), 
        n = nrow(dataset), binwidth=1.6), 
       colour = "red") 

enter image description here

+0

Rất đẹp. Tôi nghĩ rằng stat_function phải là mới. Đó là một cải tiến lớn so với cách tiếp cận trước của tôi, đó là tạo ra một khung dữ liệu của x, dnorm (x,,) đầu tiên. –

+1

@David 'stat_function' đã ở đó miễn là tôi có thể nhớ! :) – joran

+0

Điều này thật tuyệt vời - liệu có thể đếm được trên trục y chứ không phải là mật độ như trong ví dụ trên không? – fmark

Các vấn đề liên quan