Hi, I was wondering if there is a direct approach for lining up 2-column matrices according to the values of the first column. An example and a brute-force approach is given below: x <- cbind(1:10, runif(10)) y <- cbind(5:14, runif(10)) z <- cbind((-4):5, runif(10)) xx <- seq( min(c(x[,1],y[,1],z[,1])), max(c(x[,1],y[,1],z[,1])), 1) w <- cbind(xx, matrix(rep(0, 3*length(xx)), ncol=3)) w[ xx >= x[1,1] & xx <= x[10,1], 2 ] <- x[,2] w[ xx >= y[1,1] & xx <= y[10,1], 3 ] <- y[,2] w[ xx >= z[1,1] & xx <= z[10,1], 4 ] <- z[,2] w I appreciate any pointers. Thanks. Christos Hatzis, Ph.D. Nuvera Biosciences, Inc. 400 West Cummings Park Suite 5350 Woburn, MA 01801 Tel: 781-938-3830 www.nuverabio.com
On Thu, 2007-02-01 at 15:05 -0500, Christos Hatzis wrote:> Hi, > > I was wondering if there is a direct approach for lining up 2-column > matrices according to the values of the first column. An example and a > brute-force approach is given below: > > x <- cbind(1:10, runif(10)) > y <- cbind(5:14, runif(10)) > z <- cbind((-4):5, runif(10)) > > xx <- seq( min(c(x[,1],y[,1],z[,1])), max(c(x[,1],y[,1],z[,1])), 1) > w <- cbind(xx, matrix(rep(0, 3*length(xx)), ncol=3)) > > w[ xx >= x[1,1] & xx <= x[10,1], 2 ] <- x[,2] > w[ xx >= y[1,1] & xx <= y[10,1], 3 ] <- y[,2] > w[ xx >= z[1,1] & xx <= z[10,1], 4 ] <- z[,2] > > w > > I appreciate any pointers. > > Thanks.How about this: x <- cbind(1:10, runif(10)) y <- cbind(5:14, runif(10)) z <- cbind((-4):5, runif(10)) colnames(x) <- c("X", "Y") colnames(y) <- c("X", "Y") colnames(z) <- c("X", "Y") xy <- merge(x, y, by = "X", all = TRUE) xyz <- merge(xy, z, by = "X", all = TRUE) xyz[is.na(xyz)] <- 0> xyzX Y.x Y.y Y 1 -4 0.0000000 0.0000000 0.3969099 2 -3 0.0000000 0.0000000 0.8943127 3 -2 0.0000000 0.0000000 0.4882819 4 -1 0.0000000 0.0000000 0.0275787 5 0 0.0000000 0.0000000 0.7562341 6 1 0.6873130 0.0000000 0.6185218 7 2 0.1930880 0.0000000 0.2318025 8 3 0.1164783 0.0000000 0.7336057 9 4 0.7408532 0.0000000 0.3006347 10 5 0.7112887 0.6383823 0.8515126 11 6 0.2719079 0.5952721 0.0000000 12 7 0.2067017 0.8178048 0.0000000 13 8 0.2085043 0.5714917 0.0000000 14 9 0.2251435 0.4032660 0.0000000 15 10 0.3471888 0.5247478 0.0000000 16 11 0.0000000 0.6899197 0.0000000 17 12 0.0000000 0.7188912 0.0000000 18 13 0.0000000 0.9133252 0.0000000 19 14 0.0000000 0.9186001 0.0000000 Note that 'xyz' will be a data frame, so just use as.matrix(xyz) to coerce back to a numeric matrix if needed. See ?merge HTH, Marc Schwartz
The zoo package has a multiway merge with optional zero fill. Here are two ways: library(zoo) merge(x = zoo(x[,2], x[,1]), y = zoo(y[,2], y[,1]), z = zoo(z[,2], z[,1]), fill = 0) # or library(zoo) X <- list(x = x, y = y, z = z) merge0 <- function(..., fill = 0) merge(..., fill = fill) do.call("merge0", lapply(X, function(x) zoo(x[,2], x[,1]))) To get more info on zoo try: vignette("zoo") On 2/1/07, Christos Hatzis <christos at nuverabio.com> wrote:> Hi, > > I was wondering if there is a direct approach for lining up 2-column > matrices according to the values of the first column. An example and a > brute-force approach is given below: > > x <- cbind(1:10, runif(10)) > y <- cbind(5:14, runif(10)) > z <- cbind((-4):5, runif(10)) > > xx <- seq( min(c(x[,1],y[,1],z[,1])), max(c(x[,1],y[,1],z[,1])), 1) > w <- cbind(xx, matrix(rep(0, 3*length(xx)), ncol=3)) > > w[ xx >= x[1,1] & xx <= x[10,1], 2 ] <- x[,2] > w[ xx >= y[1,1] & xx <= y[10,1], 3 ] <- y[,2] > w[ xx >= z[1,1] & xx <= z[10,1], 4 ] <- z[,2] > > w > > I appreciate any pointers. > > Thanks. > > Christos Hatzis, Ph.D. > Nuvera Biosciences, Inc. > 400 West Cummings Park > Suite 5350 > Woburn, MA 01801 > Tel: 781-938-3830 > www.nuverabio.com > > ______________________________________________ > R-help at stat.math.ethz.ch 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. >
Thanks Gabor. This is along the lines of what I was looking for. In fact the merge function for zoo objects (ordered) turns out to be almost an order of magnitude faster than the generic merge function for my problem:> system.time(+ zz <- merge( spec.1 = zoo(nmr.spectra.serum[[1]]$V2, nmr.spectra.serum[[1]]$V1), + spec.2 = zoo(nmr.spectra.serum[[2]]$V2, nmr.spectra.serum[[2]]$V1), fill=NA ) + ) [1] 0.74 0.07 0.82 NA NA> system.time(+ ww <- merge(nmr.spectra.serum[[1]], nmr.spectra.serum[[2]], by="V1", all=T, sort=T) + ) [1] 6.85 0.05 6.94 NA NA> head(zz)spec.1 spec.2 -1322.2 -0.651 NA -1321.9 -0.266 NA -1321.7 -0.962 NA -1321.4 -0.602 NA -1321.2 0.753 NA -1320.9 1.212 NA> head(ww)V1 V2.x V2.y 1 -1322.2 -0.651 NA 2 -1321.9 -0.266 NA 3 -1321.7 -0.962 NA 4 -1321.4 -0.602 NA 5 -1321.2 0.753 NA 6 -1320.9 1.212 NA>Thanks again. -Christos -----Original Message----- From: Gabor Grothendieck [mailto:ggrothendieck at gmail.com] Sent: Thursday, February 01, 2007 7:25 PM To: christos at nuverabio.com Cc: r-help at stat.math.ethz.ch Subject: Re: [R] Lining up x-y datasets based on values of x The zoo package has a multiway merge with optional zero fill. Here are two ways: library(zoo) merge(x = zoo(x[,2], x[,1]), y = zoo(y[,2], y[,1]), z = zoo(z[,2], z[,1]), fill = 0) # or library(zoo) X <- list(x = x, y = y, z = z) merge0 <- function(..., fill = 0) merge(..., fill = fill) do.call("merge0", lapply(X, function(x) zoo(x[,2], x[,1]))) To get more info on zoo try: vignette("zoo") On 2/1/07, Christos Hatzis <christos at nuverabio.com> wrote:> Hi, > > I was wondering if there is a direct approach for lining up 2-column > matrices according to the values of the first column. An example and > a brute-force approach is given below: > > x <- cbind(1:10, runif(10)) > y <- cbind(5:14, runif(10)) > z <- cbind((-4):5, runif(10)) > > xx <- seq( min(c(x[,1],y[,1],z[,1])), max(c(x[,1],y[,1],z[,1])), 1) w > <- cbind(xx, matrix(rep(0, 3*length(xx)), ncol=3)) > > w[ xx >= x[1,1] & xx <= x[10,1], 2 ] <- x[,2] w[ xx >= y[1,1] & xx <= > y[10,1], 3 ] <- y[,2] w[ xx >= z[1,1] & xx <= z[10,1], 4 ] <- z[,2] > > w > > I appreciate any pointers. > > Thanks. > > Christos Hatzis, Ph.D. > Nuvera Biosciences, Inc. > 400 West Cummings Park > Suite 5350 > Woburn, MA 01801 > Tel: 781-938-3830 > www.nuverabio.com > > ______________________________________________ > R-help at stat.math.ethz.ch 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. >