Murali.MENON at fortisinvestments.com
2009-Mar-27 13:24 UTC
[R] adding matrices with common column names
folks, if i have three matrices, a, b, cc with some colnames in common, and i want to create a matrix which consists of the common columns added up, and the other columns tacked on, what's a good way to do it? i've got the following roundabout code for two matrices, but if the number of matrices increases, then i'm a bit stymied.> a <- matrix(1:20,ncol=4); colnames(a) <- c("a","b","c","d") b <- > matrix(1:20,ncol=4); colnames(b) <- c("b","c","d", "e") > cbind(a[,!(colnames(a) %in% colnames(b)), drop = FALSE],a[,intersect(colnames(a),colnames(b))] + b[,intersect(colnames(a),colnames(b)), drop = FALSE], b[,!(colnames(b) %in% colnames(a)), drop = FALSE]) a b c d e [1,] 1 7 17 27 16 [2,] 2 9 19 29 17 [3,] 3 11 21 31 18 [4,] 4 13 23 33 19 [5,] 5 15 25 35 20 now, what if i had a matrix cc? i want to perform the above operation on all three matrices a, b, cc.> cc <- matrix(1:10,ncol=2); colnames(cc) <- c("e","f")i need to end up with: a b c d e f [1,] 1 7 17 27 17 6 [2,] 2 9 19 29 19 7 [3,] 3 11 21 31 21 8 [4,] 4 13 23 33 23 9 [5,] 5 15 25 35 25 10 and, in general, with multiple matrices with intersecting colnames? thanks, murali
one approach is:
a <- matrix(1:20,ncol=4); colnames(a) <-
c("a","b","c","d")
b <- matrix(1:20,ncol=4); colnames(b) <-
c("b","c","d", "e")
cc <- matrix(1:10,ncol=2); colnames(cc) <- c("e","f")
f <- function (...) {
mat.lis <- list(...)
unq.cnams <- unique(unlist(lapply(mat.lis, colnames)))
out <- matrix(0, nrow(mat.lis[[1]]), length(unq.cnams),
dimnames = list(NULL, unq.cnams))
for (i in seq_along(mat.lis)) {
mm <- mat.lis[[i]]
out[, colnames(mm)] <- out[, colnames(mm)] + mm
}
out
}
f(a, b)
f(a, cc)
f(a, b, cc)
I hope it helps.
Best,
Dimitris
Murali.MENON at fortisinvestments.com wrote:> folks,
>
> if i have three matrices, a, b, cc with some colnames in common, and i
> want to create a matrix which consists of the common columns added up,
> and the other columns tacked on, what's a good way to do it? i've
got
> the following roundabout code for two matrices, but if the number of
> matrices increases, then i'm a bit stymied.
>
>> a <- matrix(1:20,ncol=4); colnames(a) <-
c("a","b","c","d") b <-
>> matrix(1:20,ncol=4); colnames(b) <-
c("b","c","d", "e")
>> cbind(a[,!(colnames(a) %in% colnames(b)), drop = FALSE],
> a[,intersect(colnames(a),colnames(b))] +
> b[,intersect(colnames(a),colnames(b)), drop = FALSE],
> b[,!(colnames(b) %in% colnames(a)), drop = FALSE])
>
> a b c d e
> [1,] 1 7 17 27 16
> [2,] 2 9 19 29 17
> [3,] 3 11 21 31 18
> [4,] 4 13 23 33 19
> [5,] 5 15 25 35 20
>
> now, what if i had a matrix cc? i want to perform the above operation on
> all three matrices a, b, cc.
>
>> cc <- matrix(1:10,ncol=2); colnames(cc) <-
c("e","f")
>
> i need to end up with:
>
> a b c d e f
> [1,] 1 7 17 27 17 6
> [2,] 2 9 19 29 19 7
> [3,] 3 11 21 31 21 8
> [4,] 4 13 23 33 23 9
> [5,] 5 15 25 35 25 10
>
> and, in general, with multiple matrices with intersecting colnames?
>
> thanks,
>
> murali
>
> ______________________________________________
> 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.
>
--
Dimitris Rizopoulos
Assistant Professor
Department of Biostatistics
Erasmus University Medical Center
Address: PO Box 2040, 3000 CA Rotterdam, the Netherlands
Tel: +31/(0)10/7043478
Fax: +31/(0)10/7043014
Shucks, Dimitris beat me to it. And his code is a bit more elegant than
mine. But since I did the work I may as well post it, right?
This version incorporates a couple of error checks to make sure all your
arguments are matrices with the same number of rows.
add.by.name <- function(...){
args <- list(...)
mat.test <- sapply(args,is.matrix)
if(FALSE %in% mat.test) stop("All arguments must be matrices")
mat.row <- unique(sapply(args,nrow))
if(length(mat.row)>1) stop("All matrices must have the same number of
rows")
all.names <- unique(as.vector(sapply(args,colnames)))
sum.mat <- matrix(0,nrow=mat.row,ncol=length(all.names))
colnames(sum.mat) <- all.names
for(i in 1:length(args)){
tmp <- args[[i]]
sum.mat[,colnames(tmp)] <- sum.mat[,colnames(tmp)] + tmp
}
return(sum.mat)
}
m1 <- matrix(1:20,ncol=4); colnames(m1) <-
c("a","b","c","d")
m2 <- matrix(1:20,ncol=4); colnames(m2) <-
c("b","c","d","e")
m3 <- matrix(1:20,ncol=4); colnames(m3) <-
c("a","b","d","e")
add.by.name(m1,m2,m3)
-----Original Message-----
From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org]
On Behalf Of Murali.MENON at fortisinvestments.com
Sent: Friday, March 27, 2009 9:25 AM
To: r-help at r-project.org
Subject: [R] adding matrices with common column names
folks,
if i have three matrices, a, b, cc with some colnames in common, and i
want to create a matrix which consists of the common columns added up,
and the other columns tacked on, what's a good way to do it? i've got
the following roundabout code for two matrices, but if the number of
matrices increases, then i'm a bit stymied.
> a <- matrix(1:20,ncol=4); colnames(a) <-
c("a","b","c","d") b <-
> matrix(1:20,ncol=4); colnames(b) <-
c("b","c","d", "e")
> cbind(a[,!(colnames(a) %in% colnames(b)), drop = FALSE],
a[,intersect(colnames(a),colnames(b))] +
b[,intersect(colnames(a),colnames(b)), drop = FALSE],
b[,!(colnames(b) %in% colnames(a)), drop = FALSE])
a b c d e
[1,] 1 7 17 27 16
[2,] 2 9 19 29 17
[3,] 3 11 21 31 18
[4,] 4 13 23 33 19
[5,] 5 15 25 35 20
now, what if i had a matrix cc? i want to perform the above operation on
all three matrices a, b, cc.
> cc <- matrix(1:10,ncol=2); colnames(cc) <-
c("e","f")
i need to end up with:
a b c d e f
[1,] 1 7 17 27 17 6
[2,] 2 9 19 29 19 7
[3,] 3 11 21 31 21 8
[4,] 4 13 23 33 23 9
[5,] 5 15 25 35 25 10
and, in general, with multiple matrices with intersecting colnames?
thanks,
murali
______________________________________________
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.
==================================
P Please consider the environment before printing this e-mail
Cleveland Clinic is ranked one of the top hospitals
in America by U.S. News & World Report (2008).
Visit us online at http://www.clevelandclinic.org for
a complete listing of our services, staff and
locations.
Confidentiality Note: This message is intended for use\...{{dropped:13}}