尝试使用ggplot2的geom_smooth()函数展示原始数据和拟合数据(nls + dnorm)。

13

我正在探索一些数据,因此我想做的第一件事是尝试将正态(高斯)分布拟合到它上面。这是我第一次在R中尝试这样做,所以我会一步一步来。首先,我预先将我的数据进行了分箱:

myhist = data.frame(size = 10:27, counts = c(1L, 3L, 5L, 6L, 9L, 14L, 13L, 23L, 31L, 40L, 42L, 22L, 14L, 7L, 4L, 2L, 2L, 1L) )

qplot(x=size, y=counts, data=myhist)

plot1

由于我想要计数,因此我需要添加一个标准化因子(N)来扩大密度:

fit = nls(counts ~ N * dnorm(size, m, s), data=myhist, start=c(m=20, s=5, N=sum(myhist$counts)) )   

然后我创建了适合显示的拟合数据,一切都很顺利:

x = seq(10,30,0.2)
fitted = data.frame(size = x, counts=predict(fit, data.frame(size=x)) )
ggplot(data=myhist, aes(x=size, y=counts)) + geom_point() + geom_line(data=fitted)

plot2

我很兴奋地发现了这个帖子,其中讨论了使用geom_smooth()一步完成所有操作的方法,但我无法使其工作:

以下是我的尝试和结果:

ggplot(data=myhist, aes(x=size, y=counts)) + geom_point() + geom_smooth(method="nls", formula = counts ~ N * dnorm(size, m, s), se=F, start=list(m=20, s=5, N=300, size=10))

Error in method(formula, data = data, weights = weight, ...) : 
  parameters without starting value in 'data': counts

这个错误似乎表明它正在尝试拟合观察变量counts,但这没有任何意义,如果我为counts指定一个“起始”值,它会可预见地崩溃:

fitting parameters ‘m’, ‘s’, ‘N’, ‘size’, ‘counts’ without any variables

Error in eval(expr, envir, enclos) : object 'counts' not found

有什么想法我做错了什么?当然这不是世界末日,但步骤越少越好,而且您总是能够提供最优雅的解决方案来完成这些常见任务。

先行致谢!

Jeffrey


1
您提到正在探索数据。拟合必须是nls吗?使用简单的ggplot(myhist,aes(x = size,y = counts))+ geom_point()+ geom_smooth()可以获得一个更不起眼的loess fit。虽然我希望有人能够解释如何让nls工作...这相当神秘。 - Matt Parker
我(勉强)从自然科学转到统计学,所以“探索”往往意味着“时间拟合高斯分布!”虽然如此,我找到了一些很棒的资源,比如Ricci的《Fitting Distributions in R》(http://cran.r-project.org/doc/contrib/Ricci-distributions-en.pdf)和这篇关于fitdistr()的SO答案(https://dev59.com/-W855IYBdhLWcg3wiUz1),但是没有一个旧的东西使用ggplot2。 - Jeffrey Breen
1个回答

17

第一个错误表明ggplot2在数据中找不到在公式中使用的变量'count'。

统计信息在映射后进行,即大小->x,计数->y。

以下是使用geom_smooth中nls的示例:

ggplot(data=myhist, aes(x=size, y=counts)) + geom_point() + 
  geom_smooth(method="nls", formula = y ~ N * dnorm(x, m, s), se=F, 
              start=list(m=20, s=5, N=300)) 
使用 x 和 y 来指定公式而不是 size 和 counts,这就是重点。

谢谢,kohske -- 这解释得很清楚! - Jeffrey Breen
太棒了!看起来 geom_smooth 的语法自 2010 年以来有些变化。现在(2022)的等效代码是:geom_smooth(method="nls", formula = y ~ N * dnorm(x, m, s), se=F, method.args = list(start=list(m=20, s=5, N=300))) - jdobres

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接