根据您提供的信息,听起来您希望将所有观察结果保留在x 中,然后对于x 中的每个观察结果,您希望在y 中找到最小化列之间距离的观察结果@ 987654325@ 和zP。如果那是您正在寻找的东西,那么这样的东西可能会起作用
> library(data.table)
> x <- data.table(z = c(0.231, 0.045, 0.632, 0.217, 0.092), k = c("A","A","B","B","B"))
> y <- data.table(zP = c(0.010, 0.813, 0.017, 0.421), m = c(1,2,3,4))
> x
z k
1: 0.231 A
2: 0.045 A
3: 0.632 B
4: 0.217 B
5: 0.092 B
> y
zP m
1: 0.010 1
2: 0.813 2
3: 0.017 3
4: 0.421 4
> find.min.zP <- function(x){
+ y[which.min(abs(x - zP)), zP]
+ }
> x[, zP := find.min.zP(z), by = z]
> x
z k zP
1: 0.231 A 0.421
2: 0.045 A 0.017
3: 0.632 B 0.813
4: 0.217 B 0.017
5: 0.092 B 0.017
> merge(x, y, by="zP", all.x = T, all.y = F)
zP z k m
1: 0.017 0.045 A 3
2: 0.017 0.217 B 3
3: 0.017 0.092 B 3
4: 0.421 0.231 A 4
5: 0.813 0.632 B 2
鉴于我经常使用data.table,这是我脑海中突然出现的解决方案。请注意,在这里使用data.table 可能是也可能不是最优雅的方式,甚至可能不是最快的方式(尽管如果x 和y 很大,一些涉及data.table 的解决方案可能是最快的) .另请注意,这可能是使用data.table“糟糕”的一个例子,因为我没有努力优化速度。如果速度很重要,我强烈建议您阅读github wiki 上的有用文档。希望对您有所帮助。
编辑:
正如我所怀疑的,data.table 提供了一种更好的方法,Arun 在 cmets 中指出了这一点。
> setkey(x, z)
> setkey(y, zP)
> y[x, roll="nearest"]
zP m k
1: 0.045 3 A
2: 0.092 3 B
3: 0.217 3 B
4: 0.231 4 A
5: 0.632 2 B
唯一的区别是 z 列现在被命名为 zP 并且原来的 zP 列已经消失了。如果保留该列很重要,您始终可以将 y 中的 zP 列复制到名为 z 的新列并加入该列。
> y[, z := zP]
> setkey(x, z)
> setkey(y, z)
> y[x, roll='nearest']
zP m z k
1: 0.017 3 0.045 A
2: 0.017 3 0.092 B
3: 0.017 3 0.217 B
4: 0.421 4 0.231 A
5: 0.813 2 0.632 B
这稍微减少了输入,但真正的改进在于大型数据集的计算时间。
> x <- data.table(z = runif(100000, 0, 100), k = sample(LETTERS, 100000, replace = T))
> y <- data.table(zP = runif(50000, 0, 100), m = sample(letters, 50000, replace = T))
> start <- proc.time()
> x[, zP := find.min.zP(z), by = z]
> slow <- merge(x, y, by="zP", all.x = T, all.y = F)
> proc.time() - start
user system elapsed
104.849 0.072 106.432
> x[, zP := NULL] # Drop the zP column we added to x doing the merge the slow way
> start <- proc.time()
> y[, z := zP]
> setkey(x, z)
> setkey(y, z)
> fast <- y[x, roll='nearest']
> proc.time() - start
user system elapsed
0.046 0.000 0.045
# Reorder the rows and columns so that we can compare the two data tables
> setkey(slow, z)
> setcolorder(slow, c("z", "zP", "k", "m"))
> setcolorder(fast, c("z", "zP", "k", "m"))
> all.equal(slow, fast)
TRUE
请注意,更快的方法要快 2,365 倍!对于具有超过 100,000 个观测值的数据集(这些天相对较小),我预计时间增益会更加显着。这就是为什么如果您正在处理大型数据集,阅读 data.table 文档是值得的。通过使用内置方法,您通常可以实现非常大的加速,但除非您查看,否则您不会知道它们的存在。