这是一个简单的函数来做你想做的事,假设你的数据是单峰的,这里使用线性插值:
# FUNCTION TO INFER FWHM USING LINEAR INTERPOLATION
fwhm = function(x, y) {
halfheight = max(y)/2
id.maxy = which.max(y)
y1 = y[1:id.maxy]
y2 = y[id.maxy:length(y)]
x1 = x[1:id.maxy]
x2 = x[id.maxy:length(y)]
x.start = approx(x=y1,y=x1, xout=halfheight, method="linear")$y # or without interpolation: x[which.min(abs(y1-halfheight))]
x.stop = approx(x=y2,y=x2, xout=halfheight, method="linear")$y # or without interpolation: x[which.min(abs(y2-halfheight))+id.maxy]
fwhm = x.stop-x.start
width = fwhm/(2*sqrt(2*log(2)))
return(list(fwhm=fwhm, width=width))
}
# GAUSSIAN PEAK FUNCTION WITH MODE AT u, WIDTH AT INFLECTION POINT w (FWHM=2.355*w) AND PEAK HEIGHT h
gauspeak=function(x, u, w, h=1) h*exp(((x-u)^2)/(-2*(w^2)))
# EXAMPLE
x = seq(0,200,length.out=1000)
y = gauspeak(x=x, u=100, w=10, h=100)
fwhm(x=x, y=y)
# $`fwhm`
# [1] 23.54934
#
# $width
# [1] 10.00048
您也可以使用该spline()
函数代替approx()
三次样条插值而不是线性插值。如果您的数据是单峰的但有噪声,您可以首先使用平滑您的数据smooth.spline()
(如果您的数据严格为正,则可能在一定log(y+1E-20)
范围内,之后您可以反向转换为原始比例)。