我有一个向量
set.seed(2)
x <- sample.int(20, 5)
[1] 4 14 11 3 16
现在,对于我想找到的每个元素
所述具有最小距离元件(min(abs(x[i]-x[-i]))
用于元件i
),其在这里将
[1] 3 16 14 4 14
具有最小距离的元素的(第一)索引,此处为
[1] 4 5 2 1 2
关键是不考虑元素本身,而是仅考虑所有其他元素,这就是为什么R-在向量中找到最接近值的最快方法不是答案。
如果实际答案在那里,对不起-我没有找到。
1)Rfastdista
在Rfast中使用我们可以获得最接近的两个索引。将第二个最接近的值作为最接近的值。
library(Rfast)
x <- c(4, 14, 11, 3, 16) # input
x[ dista(x, x, k = 2, index = TRUE)[, 2] ]
## [1] 3 16 14 4 14
2)sqldf使用SQL,我们可以将DF自身(不包括相同值的值)连接起来,并以最小的距离进入行。
DF <- data.frame(x) # x is from (1)
sqldf("select a.x, b.x nearest, min(abs(a.x - b.x))
from DF a
left join DF b on a.x != b.x
group by a.rowid")[1:2]
给予:
x nearest
1 4 3
2 14 16
3 11 14
4 3 4
5 16 14
3)zoo对输入进行排序,获取与每个元素任一侧的最小差异相对应的值,然后将其排序。
library(zoo)
ix <- order(x)
least <- function(x) if (x[2] - x[1] < x[3] - x[2]) x[1] else x[3]
rollapply(c(-Inf, x[ix], Inf), 3, least)[order(ix)]
## [1] 3 16 14 4 14
4)Base R使用ix
和least
自(3),我们可以仅使用基本函数来模仿(3),如下所示。
apply(embed(c(-Inf, x[ix], Inf), 3)[, 3:1], 1, least)[order(ix)]
## [1] 3 16 14 4 14
4a)这种稍短的变化也可以起作用:
-apply(embed(-c(-Inf, x[ix], Inf), 3), 1, least)[order(ix)]
## [1] 3 16 14 4 14
4b)进一步简化,我们有以下基本解决方案,再次ix
基于(3):
xx <- x[ix]
x1 <- c(-Inf, xx[-length(xx)])
x2 <- c(xx[-1], Inf)
ifelse(xx - x1 < x2 - xx, x1, x2)[order(ix)]
## [1] 3 16 14 4 14
问题中的示例没有重复项,但是如果有重复项,则存在有关问题定义的一些问题。例如,c(1, 3, 4, 1)
如果我们查看第一个值1,则存在另一个正好等于它的值,因此最接近的值是1。另一种解释是,应返回不等于1的最接近的值,在这种情况下为3.在上面的代码中,sqldf
解决方案给出的最接近值不等于当前值,而其他解决方案给出的其余值之中最接近的值。
如果我们想使最接近的解释不等于其他解释,sqldf
则可以rle
在命令压缩后将其压缩为唯一值,然后再使用inverse.rle
,如修改后的4b所示:
x <- c(1, 3, 4, 1)
ix <- order(x)
r <- rle(x[ix])
xx <- r$values
x1 <- c(-Inf, xx[-length(xx)])
x2 <- c(xx[-1], Inf)
r$values <- ifelse(xx - x1 < x2 - xx, x1, x2)
inverse.rle(r)[order(ix)]
## [1] 3 4 3 3
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句