发帖人没有询问是否查找值 if exact=FALSE
,但我将其添加为我自己和可能其他人参考的答案。
如果您正在查找分类值,请使用其他答案。
Excelvlookup
还允许您将数值与第 4 个参数 (1) 近似匹配match=TRUE
。我想像match=TRUE
在温度计上查找值一样。默认值为 FALSE,非常适合分类值。
如果您想大致匹配(执行查找),R 有一个名为 的函数findInterval
,它(顾名思义)将找到包含连续数值的区间/bin。
但是,假设您想要findInterval
多个值。您可以编写一个循环或使用一个应用函数。但是,我发现采用 DIY 矢量化方法更有效。
假设您有一个由 x 和 y 索引的值网格:
grid <- list(x = c(-87.727, -87.723, -87.719, -87.715, -87.711),
y = c(41.836, 41.839, 41.843, 41.847, 41.851),
z = (matrix(data = c(-3.428, -3.722, -3.061, -2.554, -2.362,
-3.034, -3.925, -3.639, -3.357, -3.283,
-0.152, -1.688, -2.765, -3.084, -2.742,
1.973, 1.193, -0.354, -1.682, -1.803,
0.998, 2.863, 3.224, 1.541, -0.044),
nrow = 5, ncol = 5)))
并且您有一些想要通过 x 和 y 查找的值:
df <- data.frame(x = c(-87.723, -87.712, -87.726, -87.719, -87.722, -87.722),
y = c(41.84, 41.842, 41.844, 41.849, 41.838, 41.842),
id = c("a", "b", "c", "d", "e", "f")
这是可视化的示例:
contour(grid)
points(df$x, df$y, pch=df$id, col="blue", cex=1.2)
![等高线图](https://i.stack.imgur.com/o1gMA.png)
您可以使用这种类型的公式找到 x 间隔和 y 间隔:
xrng <- range(grid$x)
xbins <- length(grid$x) -1
yrng <- range(grid$y)
ybins <- length(grid$y) -1
df$ix <- trunc( (df$x - min(xrng)) / diff(xrng) * (xbins)) + 1
df$iy <- trunc( (df$y - min(yrng)) / diff(yrng) * (ybins)) + 1
您可以更进一步,对 z 值执行(简单的)插值,grid
如下所示:
df$z <- with(df, (grid$z[cbind(ix, iy)] +
grid$z[cbind(ix + 1, iy)] +
grid$z[cbind(ix, iy + 1)] +
grid$z[cbind(ix + 1, iy + 1)]) / 4)
这为您提供了这些值:
contour(grid, xlim = range(c(grid$x, df$x)), ylim = range(c(grid$y, df$y)))
points(df$x, df$y, pch=df$id, col="blue", cex=1.2)
text(df$x + .001, df$y, lab=round(df$z, 2), col="blue", cex=1)
![带值的等高线图](https://i.stack.imgur.com/y3Oge.png)
df
# x y id ix iy z
# 1 -87.723 41.840 a 2 2 -3.00425
# 2 -87.712 41.842 b 4 2 -3.11650
# 3 -87.726 41.844 c 1 3 0.33150
# 4 -87.719 41.849 d 3 4 0.68225
# 6 -87.722 41.838 e 2 1 -3.58675
# 7 -87.722 41.842 f 2 2 -3.00425
请注意,ix 和 iy 也可以通过使用 的循环找到findInterval
,例如,这是第二行的一个示例
findInterval(df$x[2], grid$x)
# 4
findInterval(df$y[2], grid$y)
# 2
哪个匹配ix
并且iy
在df[2]
脚注: (1) vlookup 的第四个参数以前称为“match”,但在引入功能区后,它被重命名为“[range_lookup]”。