I am working on a process of completion (I am not sure of the correct term) of a matrix based on two coordinates considering the minimum distance, let me explain.
I have a matrix of nxm (rows and columns), of NA values and 1 see figure 1:
The goal is:
Assuming I find the extreme coordinates (a and b see figure 2), I am trying to use the vector equation of a line:
So I'm trying to create a function that uses the extreme values (a and b) and the constant k (see figure 2)
completa <- function(a, b, k){
x <- y <- NULL
resta <- b - a
u_ba <- resta / sqrt(sum(resta^2))
for (i in seq(0, 1, k)) {
posi <- a + i * u_ba
x <- c(x, posi[1])
y <- c(y, posi[2])
}
coordenadas <- round(cbind(x, y))
return(coordenadas)
}
The example matrix is in:
data_mat <- read.csv("https://www.dropbox.com/s/hz42scjuf9uib9y/data_test.csv?dl=1")
a <- c(25, 6)
b <- c(20, 10)
When using the function with the coordinates a, b and k = 0.5 (the value of k can vary between 0 and 1), the following is obtained:
completa(a,b,0.5)
# x y
#[1,] 25 6
#[2,] 25 6
#[3,] 24 7
but the expected output is:
# x y
#[1,] 25 6
#[2,] 24 7
#[3,] 23 8
#[4,] 22 9
#[5,] 21 10 # or 21 9,
#[6,] 20 10
It is evident that there is more than one solution for the line, therefore, comment that the minimum distance is preferably considered.
Finally, after having these coordinates, it would only be enough to assign them a value equal to one. The main idea is to make this process recursive. And that in the end all the coordinates of the matrix can be joined.
Please any suggestion is welcome, thank you.
as far as i see, you have made a mathematical problem. When i understand it right, you want to "hit" the squares in between your extreme coordinates to build a bridge between your 2 cluster. The error you have made is in your for loop. You are adding at the end of the loop only 1 times the unit vector of ab, so you travelled only the distance of 1 in your grid. I have corrected your code in that way, that it travels the full distance. I hope it solved your Problem:
completa <- function(a, b, k){
if(k!=0){
x <- y <- NULL
resta <- b - a
vector_length = sqrt(sum(resta^2))
for (i in seq(0, 1, length.out=(vector_length/k))) {
posi <- a + i * resta
x <- c(x, posi[1])
y <- c(y, posi[2])
}
coordenadas <- round(cbind(x, y))
coordenadas <- unique(coordenadas[,1:2])
}
if(k==0) coordenadas = a
return(coordenadas)
}
Result is
> completa(a,b,0.5)
x y
[1,] 25 6
[2,] 24 7
[3,] 23 7
[4,] 23 8
[5,] 22 8
[6,] 22 9
[7,] 21 9
[8,] 20 10
Why not just use a linear approximation between the identified extreme points and round the values...
> x_12 <- c(25, 20)
> y_12 <- c(6, 10)
> do.call(cbind, lapply(approx(x_12, y_12, xout = seq(x_12[1], x_12[2], ifelse(x_12[1]>x_12[2], -1, 1))), round))
x y
[1,] 25 6
[2,] 24 7
[3,] 23 8
[4,] 22 8
[5,] 21 9
[6,] 20 10
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With