如何得到R中线性插值的逆

时间:2013-09-16 11:14:10

标签: r

我为这个问题找了很多解决方案,但找不到可靠的自动解决方案。请在下面找到详细的自我描述。

这些是数据: data.txt中

x y
1 1
2 2
3 3
4 2
5 1

绘制为散点图:

t=read.table("data.txt",header=T)
plot(t$x,t$y,"l")

你会看到一个高峰,我现在的问题是:假设我对线性插值感到满意,那个“曲线”的半高宽是多少?因此,x I的值x0具有f(x0)= max(y)/ 2,其中f是线性插值。我尝试使用近似和一些内核密度,但我不想平滑我的数据。

非常欢迎任何意见。

2 个答案:

答案 0 :(得分:1)

这可能有很多更好的方法,但这是一个解决方案。如果我们首先知道你如何进行插值会更容易。

# Extend your line for testing
y<-c(1,2,3,2,1,2,3,4,5,4,3)

# Split into linear segments.
segments<-c(1,diff(diff(y)))!=0
seg.points<-which(c(segments,TRUE))

# Calculate desired value
val<-max(y)/2

# Loop through and find value
res<-c()
for(i in 1:(length(seg.points)-1)) {
  start<-y[seg.points[i]]
  end<-y[seg.points[i+1]]
  if ((val>=start & val<=end) | (val<=start & val >=end)) {
    slope=(end-start)/(seg.points[i+1] - seg.points[i])
    res<-c(res,seg.points[i] + ((val - start) / slope))
  }
}
res
# [1] 2.5 3.5 6.5

答案 1 :(得分:1)

这是一个简单的函数,它假设您的数据是单峰的,可以在此处使用线性插值:

# 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)尺度上进行平滑,然后再转换回原始尺度)。