在R的ggplot2中一起使用stat_function和facet_wrap

我正在尝试使用ggplot2绘制晶格类型数据,然后在样本数据上叠加正态分布以说明基础数据离正态有多远。我想让普通dist位于顶部,以具有与面板相同的均值和stdev。


这是一个例子:


library(ggplot2)


#make some example data

dd<-data.frame(matrix(rnorm(144, mean=2, sd=2),72,2),c(rep("A",24),rep("B",24),rep("C",24)))

colnames(dd) <- c("x_value", "Predicted_value",  "State_CD")


#This works

pg <- ggplot(dd) + geom_density(aes(x=Predicted_value)) +  facet_wrap(~State_CD)

print(pg)

一切都很好,并产生了一个很好的数据三面板图。如何在顶部添加法线dist?看来我会使用stat_function,但是失败了:


#this fails

pg <- ggplot(dd) + geom_density(aes(x=Predicted_value)) + stat_function(fun=dnorm) +  facet_wrap(~State_CD)

print(pg)

似乎stat_function与facet_wrap功能不兼容。我怎样才能使这两个打得更好?


- - - - - - 编辑 - - - - -


我尝试从以下两个答案中整合想法,但我仍然不存在:


使用两个答案的组合,我可以一起破解:


library(ggplot)

library(plyr)


#make some example data

dd<-data.frame(matrix(rnorm(108, mean=2, sd=2),36,2),c(rep("A",24),rep("B",24),rep("C",24)))

colnames(dd) <- c("x_value", "Predicted_value",  "State_CD")


DevMeanSt <- ddply(dd, c("State_CD"), function(df)mean(df$Predicted_value)) 

colnames(DevMeanSt) <- c("State_CD", "mean")

DevSdSt <- ddply(dd, c("State_CD"), function(df)sd(df$Predicted_value) )

colnames(DevSdSt) <- c("State_CD", "sd")

DevStatsSt <- merge(DevMeanSt, DevSdSt)


pg <- ggplot(dd, aes(x=Predicted_value))

pg <- pg + geom_density()

pg <- pg + stat_function(fun=dnorm, colour='red', args=list(mean=DevStatsSt$mean, sd=DevStatsSt$sd))

pg <- pg + facet_wrap(~State_CD)

print(pg)

这真的很近...除了正常的dist绘图有问题之外:


在此处输入图片说明


我在这里做错了什么?


千万里不及你
浏览 2284回答 3
3回答

慕工程0101907

stat_function旨在在每个面板中覆盖相同的功能。(没有明显的方法可以使函数的参数与不同的面板匹配)。正如伊恩(Ian)所建议的那样,最好的方法是自己生成法线,并将其绘制为单独的数据集(这是您之前出错的地方-合并对于这个示例来说没有意义,如果仔细看,您会看到这就是为什么您会得到奇怪的锯齿图案)。解决问题的方法如下:dd <- data.frame(&nbsp; predicted = rnorm(72, mean = 2, sd = 2),&nbsp; state = rep(c("A", "B", "C"), each = 24))&nbsp;grid <- with(dd, seq(min(predicted), max(predicted), length = 100))normaldens <- ddply(dd, "state", function(df) {&nbsp; data.frame(&nbsp;&nbsp; &nbsp; predicted = grid,&nbsp; &nbsp; density = dnorm(grid, mean(df$predicted), sd(df$predicted))&nbsp; )})ggplot(dd, aes(predicted))&nbsp; +&nbsp;&nbsp; geom_density() +&nbsp;&nbsp; geom_line(aes(y = density), data = normaldens, colour = "red") +&nbsp; facet_wrap(~ state)&nbsp;

冉冉说

我认为您需要提供更多信息。这似乎可行:&nbsp;pg <- ggplot(dd, aes(Predicted_value)) ## need aesthetics in the ggplot&nbsp;pg <- pg + geom_density()&nbsp;&nbsp;## gotta provide the arguments of the dnorm&nbsp;pg <- pg + stat_function(fun=dnorm, colour='red',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; args=list(mean=mean(dd$Predicted_value), sd=sd(dd$Predicted_value)))&nbsp;## wrap it!&nbsp;pg <- pg + facet_wrap(~State_CD)&nbsp;pg我们为每个面板提供相同的均值和sd参数。读者可以练习获得面板特定的平均值和标准偏差*;)'*'换句话说,不确定如何完成...

皈依舞

如果您不想“手工”生成正态分布线图,仍要使用stat_function并排显示图形-那么您可以考虑使用在“ Cookbook for R”上发布的“ multiplot”函数替代facet_wrap。您可以从此处将多图代码复制到您的项目中。复制代码后,请执行以下操作:# Some fake data (copied from hadley's answer)dd <- data.frame(&nbsp; predicted = rnorm(72, mean = 2, sd = 2),&nbsp; state = rep(c("A", "B", "C"), each = 24))&nbsp;# Split the data by state, apply a function on each member that converts it into a&nbsp;# plot object, and return the result as a vector.plots <- lapply(split(dd,dd$state),FUN=function(state_slice){&nbsp;&nbsp; # The code here is the plot code generation. You can do anything you would&nbsp;&nbsp; # normally do for a single plot, such as calling stat_function, and you do this&nbsp;&nbsp; # one slice at a time.&nbsp; ggplot(state_slice, aes(predicted)) +&nbsp;&nbsp; &nbsp; geom_density() +&nbsp;&nbsp; &nbsp; stat_function(fun=dnorm,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; args=list(mean=mean(state_slice$predicted),&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sd=sd(state_slice$predicted)),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; color="red")})# Finally, present the plots on 3 columns.multiplot(plotlist = plots, cols=3)
打开App,查看更多内容
随时随地看视频慕课网APP