[R] update matrix with subset of it where only row names match

jim holtman jholtman at gmail.com
Wed Nov 14 00:06:22 CET 2007


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
   1    2    3

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 <martinej.waller at ntlworld.com> 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,]    3    2
> > [2,]    7    2
> > [3,]    5    2
> >> 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 <martinej.waller at ntlworld.com> wrote:
> <snip>
>
> 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 at 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?



More information about the R-help mailing list