From two vectors (a, b) with increasing integers and eventually different lengths, I want to extract two vectors both with length n (=5) that lead to the smallest difference when subtracting a from b.
Example
a<-c(25, 89, 159, 224, 292, 358)
b<-c(1, 19, 93, 155, 230, 291)
Subtracting the following elements leads to the smallest difference:
c(25-19, 89-93, 159-155, 225-230, 291-292)
From a, 358 is excluded
From b, 1 is excluded.
The Problem: The length of the vectors can vary:
Examples
a<-c(25, 89, 159, 224, 292, 358)
b<-c(19, 93, 155, 230, 291)
a<-c(25, 89, 159, 224, 292, 358, 560)
b<-c(19, 93, 155, 230, 291)
a<-c(25, 89, 159, 224, 292, 358)
b<-c(1 , 5, 19, 93, 155, 230, 291)
Because I have to find this “best match” for >1000 vectors, I would like to built a function that takes as input the two vectors with different lengths and gives me as output the two vectors with length n=5 that lead to the smallest difference.
This works by brute force. The columns of combn.a
and combn.b
are the combinations of 5 elements from a
and b
. Each row of the two column data frame g
is a pair of column numbers of combn.a
and combn.b
respectiively. f
evaluates the sum of absolute differences of the a
and b
subsets corresponding to a row r
of g
. v
is the distance values found, one per row of g
, with ix
being the row number in g
having the least distance. From g[ix,]
we can have the column numbers of the minimizer in comb.a
and combn.b
and from those we determine the corresponding a
and b
subsets.
align5 <- function(a, b) {
combn.a <- combn(a, 5)
combn.b <- combn(b, 5)
g <- expand.grid(a = 1:ncol(combn.a), b = 1:ncol(combn.b))
f <- function(r) sum(abs(combn.a[, r[1]] - combn.b[, r[2]]))
v <- apply(g, 1, f)
ix <- which.min(v)
rbind( combn.a[, g[ix, 1] ], combn.b[,g[ix, 2] ] )
}
# test
a <- c(25, 89, 159, 224, 292, 358)
b <- c(1, 19, 93, 155, 230, 291)
align5(a, b)
## [,1] [,2] [,3] [,4] [,5]
## [1,] 25 89 159 224 292
## [2,] 19 93 155 230 291
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.