Find a specific row or value of an array vector in R

2

How to construct a function that evaluates if any line of the mat array is equal to the vec vector both in the code below:

set.seed(000)
mat <- matrix(rnorm(20),4,5)
vec <- c(1.3297993, -0.9285670,  0.7635935, -0.2992151,  0.4356833)
mat[3,]
vec
mat==vec

In addition, how do you determine if at least a vec value is in mat ?

Note: I understand that mat==vec must equal TRUE , that is, mat-vec==0 if mat-vec<tol , where tol = 1e-5 .

    
asked by anonymous 20.03.2017 / 19:50

2 answers

1

The all.equal function gives you the result you want. I did not use the mat of your example because my computer, even with the seed set, generates random numbers different from yours. So I created a new array with well-defined values.

mat  <- matrix(1:50, ncol=5)
vec1 <- c(1, 2, 3, 4, 5)
vec2 <- c(1, 11, 21, 31, 41)
vec3 <- c(5, 15, 25, 35, 45)

which(apply(mat, 1, function(x) all.equal(x, vec1)) == "TRUE")
integer(0)
which(apply(mat, 1, function(x) all.equal(x, vec2)) == "TRUE")
[1] 1
which(apply(mat, 1, function(x) all.equal(x, vec3)) == "TRUE")
[1] 5

What the all.equal function does is compare two objects in R to see if they are fairly equal. The good thing about this function is that it has an argument called tolerance (which I use below) to solve just the tolerance problem that can appear in your simulations.

Using apply , I can apply the all.equal function to all rows in the array, without requiring a loop.

Here is a function suggestion to reproduce this result:

linha <- function(matriz, vetor){
  aux <- which(apply(matriz, 1, function(matriz) all.equal(matriz, vetor, tolerance=1e-5)) == "TRUE")

  if (length(aux) > 0){
    resposta <- aux
  } else {
    resposta <- "nao existe"
  }

  return(resposta)
}

linha(mat, vec1)
[1] "nao existe"
linha(mat, vec2)
[1] 1
linha(mat, vec3)
[1] 5

To find out if at least one element of the array is in the array, use a code similar to the one above, but without the function all.equal :

which(apply(mat, 1, function(x) x == vec1))
[1] 1
which(apply(mat, 1, function(x) x == vec2))
[1] 1 2 3 4 5
which(apply(mat, 1, function(x) x == vec3))
[1] 21 22 23 24 25

So you'll know exactly what mat positions have elements of vec .

    
21.03.2017 / 02:16
1

Eat function below you can compare either the rows or columns of an array with a vector, respected a numerical tolerance level. If fun = all you compare all elements of the vector. If fun = any you check if at least one element of the vector is equal (respecting the order):

search_vec <- function(mat, vec, dim = 1, tol = 1e-7, fun = all)
  which(apply(mat, dim, function(x) fun(abs(x - vec) < tol)))

Applying to your case, we look for the vec vector on the lines of the mat array, comparing all elements. The function returns line 3 as a response:

search_vec(mat, vec)
[1] 3

In another case, suppose we change the first value of vec . If you search for all elements equal, the answer will be empty.

vec[1] <- 10
search_vec(mat, vec)
integer(0)

But if you ask for fun = any , the function checks if at least one element is equal, and the answer is line 3:

search_vec(mat, vec, fun = any)
[1] 3

Another situation, suppose we want to know which line contains -0.799009249 . In this case you can also use fun = any and the answer is line 4:

search_vec(mat, -0.799009249, fun = any)
[1] 4

If you want to search for columns, change to dim = 2 .

    
25.03.2017 / 20:24