0
votes

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...

2
Try mtx[c("BE", "ES"), c("ES", "BE")] <- 0akrun
or use matrix indexing: mtx[rbind(c("BE", "ES"), c("ES", "BE"))] <- 0. Take a look at ?"[", it's worth reading two or three times.lmo
thank you! The issue is that there are hundreds of such pairs, that's why I'm looking for something which can automate itAnastasia
Typically, people request that you provide a reproducible example that illustrates your problem. Here, you should use dput on mtx and paste the results into your question. Second, you should include the additional information either by mentioning it in the text of your question and perhaps by adding a second pair in your example. Look into ?ncomb. This may be helpful. Also expand.grid. It is not clear what your data structure for your hundreds of pairs is, so you should also provide this in your question.lmo
thank you, I've adjusted the question accordinglyAnastasia

2 Answers

1
votes

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

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

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