5

I have a matrix with columns that duplicate character column names.

set.seed(1)
m <- matrix(sample(1:10,12,replace=TRUE), nrow = 3, ncol = 4, byrow = TRUE,
       dimnames = list(c("s1", "s2", "s3"),c("x", "y","x","y")))

m
   x y  x  y
s1 3 4  6 10
s2 3 9 10  7
s3 7 1  3  2

I need to sum all columns with the same column name into only one column i.e.

m <- matrix(c(9,14,13,16,10,3), nrow = 3, ncol = , byrow = TRUE,dimnames = list(c("s1", "s2", "s3"),c("x", "y")))

    x  y
s1  9 14
s2 13 16
s3 10  3

I have had a play with the simple sum in the aggregate function but haven't had any luck. Any advice? Thanks.

Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
Elizabeth
  • 6,391
  • 17
  • 62
  • 90
  • 1
    Advice #1: provide a minimal [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). – Joshua Ulrich Jul 16 '12 at 20:59
  • I can interpret your question in any number of ways. This makes it impossible to understand. Please post sample data and expected results. – Andrie Jul 16 '12 at 21:02
  • OK, now I have your sample data. This is a good start. What is the expected results? – Andrie Jul 16 '12 at 21:07
  • I just added the expected result. Thanks. – Elizabeth Jul 16 '12 at 21:10
  • You'll have to make one more edit. Since you use `sample` you introduce randomness into the sample data. This makes it not reproducible. To fix this, you need to add `set.seed(1)` or similar before the first sample. I've added this, to get you started. You'll need to updated the expected results with this specific set of data. – Andrie Jul 16 '12 at 21:14
  • PS, also add in words what the aggregation function is. Simple sum? – Andrie Jul 16 '12 at 21:14
  • Check this out: http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example (EDIT: as Joshua already pointed out! :p) – Chris Baker Jul 16 '12 at 21:15
  • Your expected results don't seem to match any reasonable function for combining columns of `m`. – Josh O'Brien Jul 16 '12 at 21:17
  • @JoshO'Brien That's because the input data is random. I edited the question to add the seed, but clearly any operation on random data will resemble randomness... Hopefully the OP will fix this in a few minutes. She seems pretty responsive. – Andrie Jul 16 '12 at 21:18
  • just fixed it so it matches. I just need to combine the columns that have the same names i.e. x and y – Elizabeth Jul 16 '12 at 21:19
  • You mean you have to *sum*. Combine can mean anything. Please be specific. – Andrie Jul 16 '12 at 21:22

2 Answers2

8

Well, this solution won't win any awards for transparency of code, but I rather like it:

nms <- colnames(m)
m %*% sapply(unique(nms),"==", nms)
#     x  y
# s1  9 14
# s2 13 16
# s3 10  3

It works by constructing a matrix that forms appropriate linear combinations of m's columns. To see how it works, pick apart the second line into its two component matrices, which are multiplied together using %*%, like this:

 -          -      -   -
|  3 4  6 10 |    | 1 0 |
|  3 9 10  7 |    | 0 1 |
|  7 1  3  2 |    | 1 0 |
 -          -     | 0 1 |
                   -   -
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
  • +1 Because after all my work to figure out what the OP wanted, you still managed to steal it :-) Plus, I have no idea what you did! – Andrie Jul 16 '12 at 21:40
  • Thanks. It works perfectly but I don't exactly understand why at the moment but will pick it apart in time. – Elizabeth Jul 16 '12 at 21:41
  • @Elizabeth -- I just added a bit of explanation. There are a bunch of R tricks in that short line of code; it may not be clear but (for the same reason) it'll probably reward whatever attention you give it. – Josh O'Brien Jul 16 '12 at 21:53
  • Awesome - I just got this working for sparse Matrix object too, using a sparse logical matrix times a dgCMatrix. – Ken Benoit Apr 21 '16 at 16:31
7
nms <- colnames(m)
sapply(unique(nms), function(i)rowSums(m[, nms==i]))

   x  y
s1  9 14
s2 13 16
s3 10  3
Andrie
  • 176,377
  • 47
  • 447
  • 496
  • Thank you for helping me clarify the question and also for your answer! – Elizabeth Jul 16 '12 at 21:42
  • 1
    +1 I do feel like a thief, and would've fessed up earlier if I hadn't been behind some kind of firewall that was treating me like a robot, and not letting me make any comments at all. Still shocked that I got the accept with my odd little line of code! – Josh O'Brien Jul 16 '12 at 21:57
  • 4
    @JoshO'Brien I'm afraid you fail the Turing test. Only a robot will dream up such an obfuscated answer, and then make up such an unlikely excuse. – Andrie Jul 16 '12 at 22:03