为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

千万里不及你 2019-11-13 13:38:30
我正在尝试使用ggplot2绘制晶格类型数据,然后在样本数据上叠加正态分布以说明基础数据离正态有多远。我想让普通dist位于顶部,以具有与面板相同的均值和stdev。这是一个例子:library(ggplot2)#make some example datadd<-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 workspg <- ggplot(dd) + geom_density(aes(x=Predicted_value)) +  facet_wrap(~State_CD)print(pg)一切都很好,并产生了一个很好的数据三面板图。如何在顶部添加法线dist?看来我会使用stat_function,但是失败了:#this failspg <- 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 datadd<-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绘图有问题之外:在此处输入图片说明我在这里做错了什么?
查看完整描述

3 回答

?
慕工程0101907

TA贡献1887条经验 获得超5个赞

stat_function旨在在每个面板中覆盖相同的功能。(没有明显的方法可以使函数的参数与不同的面板匹配)。


正如伊恩(Ian)所建议的那样,最好的方法是自己生成法线,并将其绘制为单独的数据集(这是您之前出错的地方-合并对于这个示例来说没有意义,如果仔细看,您会看到这就是为什么您会得到奇怪的锯齿图案)。


解决问题的方法如下:


dd <- data.frame(

  predicted = rnorm(72, mean = 2, sd = 2),

  state = rep(c("A", "B", "C"), each = 24)


grid <- with(dd, seq(min(predicted), max(predicted), length = 100))

normaldens <- ddply(dd, "state", function(df) {

  data.frame( 

    predicted = grid,

    density = dnorm(grid, mean(df$predicted), sd(df$predicted))

  )

})


ggplot(dd, aes(predicted))  + 

  geom_density() + 

  geom_line(aes(y = density), data = normaldens, colour = "red") +

  facet_wrap(~ state) 


查看完整回答
反对 回复 2019-11-13
?
冉冉说

TA贡献1877条经验 获得超1个赞

我认为您需要提供更多信息。这似乎可行:


 pg <- ggplot(dd, aes(Predicted_value)) ## need aesthetics in the ggplot

 pg <- pg + geom_density() 

 ## gotta provide the arguments of the dnorm

 pg <- pg + stat_function(fun=dnorm, colour='red',            

            args=list(mean=mean(dd$Predicted_value), sd=sd(dd$Predicted_value)))

 ## wrap it!

 pg <- pg + facet_wrap(~State_CD)

 pg

我们为每个面板提供相同的均值和sd参数。读者可以练习获得面板特定的平均值和标准偏差*;)


'*'换句话说,不确定如何完成...


查看完整回答
反对 回复 2019-11-13
?
皈依舞

TA贡献1851条经验 获得超3个赞

如果您不想“手工”生成正态分布线图,仍要使用stat_function并排显示图形-那么您可以考虑使用在“ Cookbook for R”上发布的“ multiplot”函数替代facet_wrap。您可以从此处将多图代码复制到您的项目中。


复制代码后,请执行以下操作:


# Some fake data (copied from hadley's answer)

dd <- data.frame(

  predicted = rnorm(72, mean = 2, sd = 2),

  state = rep(c("A", "B", "C"), each = 24)


# Split the data by state, apply a function on each member that converts it into a 

# plot object, and return the result as a vector.

plots <- lapply(split(dd,dd$state),FUN=function(state_slice){ 

  # The code here is the plot code generation. You can do anything you would 

  # normally do for a single plot, such as calling stat_function, and you do this 

  # one slice at a time.

  ggplot(state_slice, aes(predicted)) + 

    geom_density() + 

    stat_function(fun=dnorm, 

                  args=list(mean=mean(state_slice$predicted), 

                            sd=sd(state_slice$predicted)),

                  color="red")

})


# Finally, present the plots on 3 columns.

multiplot(plotlist = plots, cols=3)


查看完整回答
反对 回复 2019-11-13
  • 3 回答
  • 0 关注
  • 2277 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信