在R中给出数据点的x截距

by0*_*by0 1 math r intercept

给出一些像这样(下图)绘制的数据点,我将如何获得在特定y处相交的交叉值.例如,如果我要绘制水平线y = 1000,那么它与图表中的x值相交(作为数组)?

我的数据看起来像这样

x <- c(1, 2, 3, 4, ..., )
y <- c(1000, 1200, 900, 700, ..., )
Run Code Online (Sandbox Code Playgroud)

图1 谢谢.

MvG*_*MvG 5

要查看函数y = f(x)(我假设是连续的)与水平线y = h相交的位置,您可以在f(x)-h中查找符号变化.此符号更改的位置是函数穿过该行的位置.除非您了解有关函数的更多详细信息,以便可以在数据点之间进行插值,否则这可能是您所希望的最佳效果.

要计算R中的符号更改,您可以使用以下代码:

h <- 1000
d <- y - h
signChanges <- (d[1:(length(d)-1)] * d[2:length(d)]) <= 0
Run Code Online (Sandbox Code Playgroud)

生成的数组将比数组少一个元素x,因为每个元素对应于两个相邻x值之间的间隔.如果您的数据点完全在该行上,则该数组将包含两个后续TRUE值.如果这是一个问题,那么你可以插入

d <- ifelse(d == 0, 1, d)
Run Code Online (Sandbox Code Playgroud)

这会使数据点略微偏离线.

要获得相应的x值,您可以使用每个间隔的中心:

x2 <- (x[c(signChanges, FALSE)] + x[c(FALSE, signChanges)])/2
Run Code Online (Sandbox Code Playgroud)

或者您可以在两个相邻数据点之间执行线性插值:

left <- c(signChanges, FALSE)
right <- c(FALSE, signChanges)
t <- (h - y[left])/(y[right] - y[left])
x2 <- (1 - t)*x[left] + t*x[right]
Run Code Online (Sandbox Code Playgroud)


Die*_*nne 5

在没有平滑的情况下查找阈值交叉很少给出明确定义的值.玩下面的内容:

data(sunspots)
sunspots = as.numeric(sunspots)
smoothover = 21 # Try smaller values here to see the failure
y = filter(sunspots,rep(1/smoothover,smoothover),circular=TRUE)
plot(y)
thresh =30
abline(h=thresh)
cross = which(diff(sign(y-thresh))!=0)-1
rug(cross)
Run Code Online (Sandbox Code Playgroud)

如果你想得到"精确"的阈值交叉(如果平滑是如此重要,那么确切的是什么?)你应该首先使用上面的近似来获得交叉点周围的区域,然后进行二次或线性插值,例如5点.