volfi
volfi

Reputation: 477

How to replace elements in char matrix with values from named vector in R

I have a char matrix and a named vector of doubles where the vector names correspond to the elements in the char matrix. How can I replace the matrix elements by their corresponding doubles?

named_vec <- setNames(c(1,2,3), c("a","b","c"))
a b c 
1 2 3 

char_mat <- matrix(c("a","b","b","c"), nrow = 2)
     [,1] [,2]
[1,] "a"  "b" 
[2,] "b"  "c" 

The resulting matrix should look like this

result_mat <- matrix(c("1","2","2","3"), nrow = 2)
     [,1] [,2]
[1,] "1"  "2" 
[2,] "2"  "3" 

Upvotes: 0

Views: 471

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 174606

It is always easier if you provide a sample of data to work with - I have had to create a small example here which may or may not match your setup:

set.seed(69)
char_matrix <- matrix(letters[1:16], nrow = 4)
named_vec <- sample(16)
names(named_vec) <- sample(letters[1:16])

So the character matrix looks like this:

char_matrix
#>      [,1] [,2] [,3] [,4]
#> [1,] "a"  "e"  "i"  "m" 
#> [2,] "b"  "f"  "j"  "n" 
#> [3,] "c"  "g"  "k"  "o" 
#> [4,] "d"  "h"  "l"  "p"

And the named vector of doubles looks like this:

named_vec
#>  n  m  c  l  p  o  e  f  d  i  j  k  h  a  g  b 
#> 16  1 11  2  8  7 14  6  5 10 13  9  3 12 15  4

Now you can use match(names(named_vec), char_matrix) to get the indices of char_matrix where the names of named_vec are to be found. So you can simply write named_vec into these indices:

char_matrix[match(names(named_vec), char_matrix)] <- named_vec

If you have multiple matches in char_matrix this approach won't work, so you can use a loop instead:

for(i in seq_along(named_vec)) {
  char_matrix[which(char_matrix == names(named_vec)[i])] <- named_vec[i]
}

Presumably you want the final matrix to be numeric rather than character, so you will also need to change the mode of the matrix from character to numeric:

mode(char_matrix) <- "numeric"

Which gives you your final result:

char_matrix
#>      [,1] [,2] [,3] [,4]
#> [1,]   12   14   10    1
#> [2,]    4    6   13   16
#> [3,]   11   15    9    7
#> [4,]    5    3    2    8

Created on 2020-07-01 by the reprex package (v0.3.0)

Upvotes: 2

Related Questions