2012-04-15 27 views
6

Tengo dos vectores con unos pocos miles de puntos, pero generalicé aquí:R: encontrar el índice más cercana

A <- c(10, 20, 30, 40, 50) 
b <- c(13, 17, 20) 

¿Cómo puedo obtener los índices del A de que son más cercana-b? El resultado esperado sería c(1, 2, 2).

sé que findInterval sólo puede buscar el primer caso, y no el más cercano, y estoy consciente de que which.min(abs(b[2] - A)) se está calentando, pero no puedo encontrar la manera de vectorizar para trabajar con vectores largos de ambos A y b.

Respuesta

11

Puede simplemente poner su código de forma saptada. Creo que esto tiene la misma velocidad que un bucle así que no es técnicamente vectorizado sin embargo:

sapply(b,function(x)which.min(abs(x - A))) 
+3

Tenga en cuenta que 'which.min()' solo devuelve la primera coincidencia. Puede haber otros elementos que estén igualmente cercanos. –

11

FindInterval te lleva muy cerca. Sólo tienes que elegir entre el offset y devuelve el siguiente:

#returns the nearest occurence of x in vec 
nearest.vec <- function(x, vec) 
{ 
    smallCandidate <- findInterval(x, vec, all.inside=TRUE) 
    largeCandidate <- smallCandidate + 1 
    #nudge is TRUE if large candidate is nearer, FALSE otherwise 
    nudge <- 2 * x > vec[smallCandidate] + vec[largeCandidate] 
    return(smallCandidate + nudge) 
} 

nearest.vec(b,A) 

retornos (1,2,2), y debe comparable a FindInterval en el rendimiento.

+0

Realmente útil, gracias. Estoy sorprendido de que no haya algo para hacer esto en la base. ¡Lo que probablemente significa que existe y que no me doy cuenta ...! – Flyto

0

Aquí hay una solución que usa la función de R a menudo pasada por alto outer. No estoy seguro si funcionará mejor, pero evita sapply.

A <- c(10, 20, 30, 40, 50) 
b <- c(13, 17, 20) 

dist <- abs(outer(A, b, '-')) 
result <- apply(dist, 2, which.min) 

# [1] 1 2 2 
Cuestiones relacionadas