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

时间:2012-12-07 06:50:32

标签: r math intercept

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

我的数据看起来像这样

x <- c(1, 2, 3, 4, ..., )
y <- c(1000, 1200, 900, 700, ..., )

Figure 1 谢谢。

4 个答案:

答案 0 :(得分: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

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

d <- ifelse(d == 0, 1, d)

将数据点稍微移动

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

x2 <- (x[c(signChanges, FALSE)] + x[c(FALSE, signChanges)])/2

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

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

答案 1 :(得分: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)

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

答案 2 :(得分:3)

要获得实际的交叉点,您可以使用几个R的空间包:

library(sp)
library(rgeos)  ## for gIntersection()

## Wrap your line up as a SpatialLines object
x <- c(1, 2, 3, 4)
y <- c(1000, 1200, 900, 700)
SL1 <- SpatialLines(list(Lines(Line(cbind(x,y)), "A")))

## Create a horizontal SpatialLines object
SL2 <- SpatialLines(list(Lines(Line(cbind(range(x), 1010)), "B")))

## Find their point(s) of intersection
coordinates(gIntersection(SL1, SL2))
#          x    y
# 1 1.050000 1010
# 1 2.633333 1010

答案 3 :(得分:0)

我会将您的数据放在一个data.frame中:

dat = data.frame(x, y)

然后,您可以对数据集进行子集化,以仅保留y == 1000

所在的值
dat[dat$y == 1000,]

请注意,这仅适用于您使用的y值实际位于数据集中的情况。如果您在de数据集中选择y值不是字面意义(例如y = 996.345),则必须对时间序列进行一些插值,例如, this SO post,或者通过拟合一些样条函数(这可能最适合范围x = [150,900])。