交点2正常曲线

时间:2013-06-07 10:40:22

标签: r normal-distribution

虽然我认为这是一个基本问题,但我似乎无法在R中找出如何计算:

两个或更多正态分布(在直方图上拟合)的交点(我需要x值),其具有例如以下参数:

d=data.frame(mod=c(1,2),mean=c(14,16),sd=c(0.9,0.6),prop=c(0.6,0.4))

使用我的2条曲线的均值和标准差,并支持每个mod对分布的贡献比例。

3 个答案:

答案 0 :(得分:12)

您可以使用uniroot

f <- function(x) dnorm(x, m=14, sd=0.9) * .6 - dnorm(x, m=16, sd=0.6) * .4

uniroot(f, interval=c(12, 16))

$root
[1] 15.19999

$f.root
[1] 2.557858e-06

$iter
[1] 5

$estim.prec
[1] 6.103516e-05

<小时/> ETA的一些说明:

uniroot是一个单变量的根查找器,即给定一个变量f的函数x,它找到解决方程x的{​​{1}}的值}。

要使用它,您需要提供函数f(x) = 0,以及假定解决方案值所在的时间间隔。在这种情况下,f只是两个密度之间的差异;它们相交的点将是f为零的位置。在这个例子中我得到了一个区间(12,16),通过绘制一个图并看到它们在x = 15附近相交。

答案 1 :(得分:0)

很抱歉,但接受的答案并不好。另见:intersection of two curves in matlab

您可以使用以下函数获取两个根:

intersect <- function(m1, s1, m2, s2, prop1, prop2){

B <- (m1/s1^2 - m2/s2^2)
A <- 0.5*(1/s2^2 - 1/s1^2)
C <- 0.5*(m2^2/s2^2 - m1^2/s1^2) - log((s1/s2)*(prop2/prop1))

(-B + c(1,-1)*sqrt(B^2 - 4*A*C))/(2*A)
}

在你的情况下:

> intersect(14,0.9,16,0.6,0.6,0.4)
[1] 20.0 15.2

答案 2 :(得分:0)

我同意@Flounderer你应该计算两个根,但提供的功能是不完整的。当s1 = s2时,A变为零,产生Inf和NaN。

略微修改完成了该功能:

intersect <- function(m1, sd1, m2, sd2, p1, p2){

  B <- (m1/sd1^2 - m2/sd2^2)
  A <- 0.5*(1/sd2^2 - 1/sd1^2)
  C <- 0.5*(m2^2/sd2^2 - m1^2/sd1^2) - log((sd1/sd2)*(p2/p1))

  if (A!=0){
    (-B + c(1,-1)*sqrt(B^2 - 4*A*C))/(2*A)
  } else {-C/B}
} 
m1=0; sd1=2; m2=2.5; sd2=2; p1=.8; p2=.2
(is=intersect(m1,sd1,m2,sd2,p1,p2))

xs = seq(-6, 6, by=.01)
plot(xs, p1*dnorm(xs, m1, sd1), type= 'l')
lines(xs, .2*dnorm(xs, m2,sd2))
abline(v=is)

使用uniroot.all:

也可以找到一般解决方案
library(rootSolve)
f <- function(x, m1, sd1, m2, sd2, p1, p2){
  dnorm(x, m1, sd1) * p1 - dnorm(x, m2, sd2) * p2 }
uniroot.all(f, lower=-6, upper=6, m1=m1, sd1=sd1, m2=m2, sd2=sd2, p1=p1, p2=p2)