R 如何为另一个向量中的每个元素获取向量中最近的元素而不重复?

R 如何为另一个向量中的每个元素获取向量中最近的元素而不重复?,r,vector,R,Vector,我得到了这个代码,它创建了两个向量,对于a中的每个元素,我想得到b中最近的元素: a = rnorm(100) b = rnorm(100) c = vapply(a, function(x) which.min(abs(b - x)), 1) table(duplicated(c)) FALSE TRUE 61 39 正如您所看到的,这个方法会提示您提供大量的重复项,这是正常的,但我不希望有重复项。我曾想过一旦选择了索引,就从b中删除事件,但我不知道如何在vapply下执

我得到了这个代码,它创建了两个向量,对于
a
中的每个元素,我想得到
b
中最近的元素:

a = rnorm(100)
b = rnorm(100)
c = vapply(a, function(x) which.min(abs(b - x)), 1)
table(duplicated(c))

FALSE  TRUE 
   61    39 

正如您所看到的,这个方法会提示您提供大量的重复项,这是正常的,但我不希望有重复项。我曾想过一旦选择了索引,就从
b
中删除事件,但我不知道如何在
vapply

下执行,这几乎肯定可以通过矢量化进行改进,但似乎可行,并且可以完成工作:

set.seed(1)
a = rnorm(5)
b = rnorm(5)

foo <- function(a,b) {

  out <- cbind(a, bval = NA)

  for (i in seq_along(a)) {
    #which value of B is closest?
    whichB <- which.min(abs(b - a[i]))
    #Assign that value to the bval column
    out[i, "bval"] <- b[whichB]
    #Remove that value of B from being chosen again
    b <- b[-whichB]
  }

  return(out)

}

#In action
foo(a,b)
---
              a       bval
[1,] -0.6264538 -0.8204684
[2,]  0.1836433  0.4874291
[3,] -0.8356286 -0.3053884
[4,]  1.5952808  0.7383247
[5,]  0.3295078  0.5757814
set.seed(1)
a=rnorm(5)
b=rnorm(5)

foo我相信这是你能得到的最好的:
sum(abs(排序(a)-排序(b))

我正在使用
data.table
来保留
a
的原始排序:

require(data.table)

set.seed(1)

a <- rnorm(100)
b <- rnorm(100)

sum(abs(a - b))
sum(abs(sort(a) - sort(b)))

dt <- data.table(a = a, b = b)
dt[, id := .I]

# sort dt by a
setkey(dt, a)

# sort b
dt[, b := sort(b)]

# return to original order
setkey(dt, id)

dt
dt[, sum(abs(a - b))]

最接近的匹配是对向量进行排序,然后将它们配对。
b
上的下列排列应该允许您这样做

p <- order(b)[order(order(a))] # order on b and then back transform the ordering of a

sum(abs(a-b[p]))
[1] 20.76788

这是非常糟糕的编程,但可能会工作,并且是矢量化的

   a <- rnorm(100)
   b <- rnorm(100)
   #make a copy of b (you'll see why)
   b1<-b
   res<- vapply(a, function(x) {ret<-which.min(abs(b1 - x));b1[ret]<<-NA;return(ret)}, 1)

a为了清楚起见,你a在寻找一个排列,
p
,这样
sum(abs(a-b[p])
就最小化了吗?我想你可以这样说,我猜是
数据。table
的连接函数
roll=“nearest”
在这里很有用,ala@Chase这也是我的第一个想法。但我不认为这有助于避免比赛中出现重复。他们希望向量值之间有一一对应关系。@Wicelo请提供可复制的输入和输出,并解释如果
b
的每个值只能作为匹配出现一次,您希望如何确定匹配。一个
b
值是与第一个
a
值最接近的匹配值,还是与
a
值最接近的匹配值,与
b
值最接近的匹配值?你知道矢量化解决方案是否可行吗?@Wicelo这对于转换为Rcpp来说是微不足道的。好的调用-按
a
排序实际上是更聪明,会产生更好的结果。如果初始顺序不重要,只需
cbind(排序(a),排序(b)
是最直接的。我很喜欢nicola的解决方案,但你是对的。你的解决方案给出了更好的差分和。我必须研究
数据。格式化
以及
设置键
:=
操作符,我不知道这些东西编辑:事实上,詹姆斯的解决方案给出了相同的差分和是一个在线聊天工具,这正是我在发布之前所做的,但是使用了
=
而不是
请参见
?”
p <- order(b)[order(order(a))] # order on b and then back transform the ordering of a

sum(abs(a-b[p]))
[1] 20.76788
sum(abs(a-b[c]))
[1] 2.45583
   a <- rnorm(100)
   b <- rnorm(100)
   #make a copy of b (you'll see why)
   b1<-b
   res<- vapply(a, function(x) {ret<-which.min(abs(b1 - x));b1[ret]<<-NA;return(ret)}, 1)