[R] update matrix with subset of it where only row names match
I guess this has a simple solution: I have matrix 'mat1' which has row and column names, e.g.: A B C row10 0 0 row20 0 0 rown0 0 0 I have a another matrix 'mat2', essentially a subset of 'mat1' where the rownames are all in 'mat1' e.g.: B row35 row86 row54 7 I want to insert the values of matrix mat2 for column B (in reality it could be some or all of column names A, B or C, etc.) (same name in both matrices if that matters - rownames of mat2 guaranteed to be in mat1) into matrix mat1 where the rownames match, so final desired result is: matrix mat1: A B C row10 0 0 row20 0 0 row30 5 0 ... row80 6 0 ... row54 0 7 0 .. rown0 0 0 My solution was (along the lines of): mat1[rownames(mat2)%in%rownames(mat1),"B"]=mat2[,"B"] Is there a better way? It doesn't 'feel' right? Thanks - hope I explained it right (its late and I had a little drink about an hour ago,etc). Martin __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] update matrix with subset of it where only row names match
Here is one way of doing it that uses the row and column names: > # create test data > mat1 <- matrix(0, nrow=10, ncol=3) > dimnames(mat1) <- list(paste('row', 1:10, sep=''), LETTERS[1:3]) > mat2 <- matrix(1:3, ncol=1, dimnames=list(c('row3', 'row7', 'row5'), "B")) > mat2 B row3 1 row7 2 row5 3 > # create indexing matrix > indx <- cbind(match(rownames(mat2), rownames(mat1)), match(colnames(mat2), > colnames(mat1))) > indx [,1] [,2] [1,]32 [2,]72 [3,]52 > mat1[indx] <- mat2 > mat1 A B C row1 0 0 0 row2 0 0 0 row3 0 1 0 row4 0 0 0 row5 0 3 0 row6 0 0 0 row7 0 2 0 row8 0 0 0 row9 0 0 0 row10 0 0 0 On Nov 12, 2007 4:54 PM, Martin Waller <[EMAIL PROTECTED]> wrote: > I guess this has a simple solution: > > I have matrix 'mat1' which has row and column names, e.g.: > >A B C > row10 0 0 > row20 0 0 > > rown0 0 0 > > I have a another matrix 'mat2', essentially a subset of 'mat1' where the > rownames are all in 'mat1' e.g.: > >B > row35 > row86 > row54 7 > > > I want to insert the values of matrix mat2 for column B (in reality it > could be some or all of column names A, B or C, etc.) (same name in both > matrices if that matters - rownames of mat2 guaranteed to be in mat1) > into matrix mat1 where the rownames match, so final desired result is: > > matrix mat1: >A B C > row10 0 0 > row20 0 0 > row30 5 0 > ... > row80 6 0 > ... > row54 0 7 0 > .. > rown0 0 0 > > My solution was (along the lines of): > > mat1[rownames(mat2)%in%rownames(mat1),"B"]=mat2[,"B"] > > Is there a better way? It doesn't 'feel' right? > > Thanks - hope I explained it right (its late and I had a little drink > about an hour ago,etc). > > > Martin > > __ > R-help@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. > -- Jim Holtman Cincinnati, OH +1 513 646 9390 What is the problem you are trying to solve? __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] update matrix with subset of it where only row names match
jim holtman wrote: > Here is one way of doing it that uses the row and column names: > >> # create test data >> mat1 <- matrix(0, nrow=10, ncol=3) >> dimnames(mat1) <- list(paste('row', 1:10, sep=''), LETTERS[1:3]) >> mat2 <- matrix(1:3, ncol=1, dimnames=list(c('row3', 'row7', 'row5'), "B")) >> mat2 > B > row3 1 > row7 2 > row5 3 >> # create indexing matrix >> indx <- cbind(match(rownames(mat2), rownames(mat1)), match(colnames(mat2), >> colnames(mat1))) >> indx > [,1] [,2] > [1,]32 > [2,]72 > [3,]52 >> mat1[indx] <- mat2 >> mat1 > A B C > row1 0 0 0 > row2 0 0 0 > row3 0 1 0 > row4 0 0 0 > row5 0 3 0 > row6 0 0 0 > row7 0 2 0 > row8 0 0 0 > row9 0 0 0 > row10 0 0 0 > > > On Nov 12, 2007 4:54 PM, Martin Waller <[EMAIL PROTECTED]> wrote: OK - I see that, and thanks for your response, but (and excuse my ignorance, less than 2 months in R...) can you help me to see why this is 'better' (whatever that means, if anything)? From a newbie (at least my) POV, it seems less clear than my original solution. Again, please bear in mind I am relatively new so please be patient if I'm not seeing something that's obvious to yourself. I have a genuine desire to learn. Martin __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] update matrix with subset of it where only row names match
Lets take a look at your solution: > mat1 <- matrix(0, nrow=10, ncol=3) > dimnames(mat1) <- list(paste('row', 1:10, sep=''), LETTERS[1:3]) > mat2 <- matrix(1:3, ncol=1, dimnames=list(c('row3', 'row7', 'row5'), "B")) > mat2 B row3 1 row7 2 row5 3 > mat1[rownames(mat2)%in%rownames(mat1),"B"]=mat2[,"B"] Error in mat1[rownames(mat2) %in% rownames(mat1), "B"] = mat2[, "B"] : number of items to replace is not a multiple of replacement length > > rownames(mat2)%in%rownames(mat1) [1] TRUE TRUE TRUE > mat2[,"B"] row3 row7 row5 123 I got an error statement using your statement with %in%. This is because it produces a vector a 3 TRUE values are you can see above. With recycling to will the matrix, you get the error message. What you want to provide is the index value of the rows to replace in. What you would need in this case is the following statement: mat1[match(rownames(mat2), rownames(mat1)),"B"]=mat2[,"B"] Now your solution would have to be changed everytime you wanted a different column replaced. My solution determined which of the column names matched in the objects. In R, there are a number of ways of doing things. As to which is 'better', it all depends. In most cases it is probably a matter of 'style' or what a person is used to. "Better" does come into play when you are taking about performance and there might be a factor of 10X, 100X or 1000X depending on how you used some statements. I happen to like to try to break things down into some simple steps so if I have to go back later, I think I might be able to understand it again. If you are coming from a C/Java background, then one of hard things to get your mind around it to think in terms of 'vectorized' operations and also the difference in some of the ways that you create/manipulate data structures in R vs. some other languages. HTH On Nov 13, 2007 4:44 PM, Martin Waller <[EMAIL PROTECTED]> wrote: > > jim holtman wrote: > > Here is one way of doing it that uses the row and column names: > > > >> # create test data > >> mat1 <- matrix(0, nrow=10, ncol=3) > >> dimnames(mat1) <- list(paste('row', 1:10, sep=''), LETTERS[1:3]) > >> mat2 <- matrix(1:3, ncol=1, dimnames=list(c('row3', 'row7', 'row5'), "B")) > >> mat2 > > B > > row3 1 > > row7 2 > > row5 3 > >> # create indexing matrix > >> indx <- cbind(match(rownames(mat2), rownames(mat1)), match(colnames(mat2), > >> colnames(mat1))) > >> indx > > [,1] [,2] > > [1,]32 > > [2,]72 > > [3,]52 > >> mat1[indx] <- mat2 > >> mat1 > > A B C > > row1 0 0 0 > > row2 0 0 0 > > row3 0 1 0 > > row4 0 0 0 > > row5 0 3 0 > > row6 0 0 0 > > row7 0 2 0 > > row8 0 0 0 > > row9 0 0 0 > > row10 0 0 0 > > > > > > On Nov 12, 2007 4:54 PM, Martin Waller <[EMAIL PROTECTED]> wrote: > > > OK - I see that, and thanks for your response, but (and excuse my > ignorance, less than 2 months in R...) can you help me to see why this > is 'better' (whatever that means, if anything)? From a newbie (at least > my) POV, it seems less clear than my original solution. Again, please > bear in mind I am relatively new so please be patient if I'm not seeing > something that's obvious to yourself. I have a genuine desire to learn. > > > Martin > > __ > R-help@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. > -- Jim Holtman Cincinnati, OH +1 513 646 9390 What is the problem you are trying to solve? __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] update matrix with subset of it where only row names match
jim holtman wrote: > Lets take a look at your solution: > >> mat1 <- matrix(0, nrow=10, ncol=3) >> dimnames(mat1) <- list(paste('row', 1:10, sep=''), LETTERS[1:3]) >> mat2 <- matrix(1:3, ncol=1, dimnames=list(c('row3', 'row7', 'row5'), "B")) >> mat2 > B > row3 1 > row7 2 > row5 3 >> mat1[rownames(mat2)%in%rownames(mat1),"B"]=mat2[,"B"] > Error in mat1[rownames(mat2) %in% rownames(mat1), "B"] = mat2[, "B"] : > number of items to replace is not a multiple of replacement length >> rownames(mat2)%in%rownames(mat1) > [1] TRUE TRUE TRUE >> mat2[,"B"] > row3 row7 row5 >123 > > I got an error statement using your statement with %in%. This is > because it produces a vector a 3 TRUE values are you can see above. > With recycling to will the matrix, you get the error message. What > you want to provide is the index value of the rows to replace in. > What you would need in this case is the following statement: > > mat1[match(rownames(mat2), rownames(mat1)),"B"]=mat2[,"B"] > > Now your solution would have to be changed everytime you wanted a > different column replaced. My solution determined which of the column > names matched in the objects. > > In R, there are a number of ways of doing things. As to which is > 'better', it all depends. In most cases it is probably a matter of > 'style' or what a person is used to. "Better" does come into play > when you are taking about performance and there might be a factor of > 10X, 100X or 1000X depending on how you used some statements. I > happen to like to try to break things down into some simple steps so > if I have to go back later, I think I might be able to understand it > again. > > If you are coming from a C/Java background, then one of hard things to > get your mind around it to think in terms of 'vectorized' operations > and also the difference in some of the ways that you create/manipulate > data structures in R vs. some other languages. > > HTH > Thankyou for you explanation and time - very helpful. Best wishes, Martin __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.