Anastasia
Anastasia

Reputation: 105

Replace matrix elements based on column and row names

I have a matrix of elements with numeric values, e.g.:

> mtx <- as.matrix(read.csv("matrix.csv", header = TRUE, row.names = 1,sep = ","))
> head(mtx)

     BE   BG   EE   ES   FI
BE 0.00 0.75 0.17 0.28 0.48
BG 0.75 0.00 0.92 1.03 1.24
EE 0.17 0.92 0.00 0.11 0.31
ES 0.28 1.03 0.11 0.00 0.20

I want to replace values in certain elements with zero based on names of columns and rows. Namely, I want to have zero when column "BE" intersects with row "ES" and vice versa, i.e. when column "ES" intersects with row "BE", so I want to get:

     BE   BG   EE   ES   FI 
BE 0.00 0.75 0.17 0.00 0.00 
BG 0.75 0.00 0.92 1.03 1.24 
EE 0.17 0.92 0.00 0.11 0.31 
ES 0.00 1.03 0.11 0.00 0.00

I have to perform this operation for many matrices, which are larger than this example, so there are >150 pairs for which replacement is needed. Here's data structure. Replacement needed for: c('BE', 'FI', 'FR', 'DE', 'IE', 'NL', 'NO', 'SE', 'CH', 'GB', 'DK','PT','ES')

I have found function replace, but it works apparently only based on criteria applied to the values, not to the names of rows and columns of elements that contain them...

Upvotes: 0

Views: 1668

Answers (2)

Sam S.
Sam S.

Reputation: 803

akrun's answer is great. I added my solution here and hope it helps.

The matrix can be manipulated by filtering rownames and colnames to a set of names.

For example:

a=matrix(1:9,3,3)
dimnames(a) <- list(c("x","y","z"),c("x","y","z"))
a[(rownames(a) %in% c("a")), colnames(a) %in% c("d")] <- 0

But I think you want to have zero in some diagonal positions; so the solution for that will be:

a <- matrix(1:9,3,3)
dimnames(a) <- list(c("x","y","z"),c("x","y","z"))

rows <- c("x","z")
ind <- which(rownames(a) %in% rows)

diag(a)[ind] <- 0

Upvotes: 0

akrun
akrun

Reputation: 886948

As the diagonals are zero, we could subset the rows/columns and assign it to 0

 mtx[c("BE", "ES"), c("ES", "BE")] <- 0 

Upvotes: 1

Related Questions