Hi, I'd like to normalize a dataset by dividing each row by the first row. Very simple, right? I tried this:> expt.fluorX1 X2 X3 1 124 120 134 2 165 163 174 3 52 51 43 4 179 171 166 5 239 238 235>first.row <- expt.fluor[1,] > normed <- apply(expt.fluor, 1, function(r) {r / first.row}) >normed[[1]] X1 X2 X3 1 1 1 1 [[2]] X1 X2 X3 1 1.330645 1.358333 1.298507 [[3]] X1 X2 X3 1 0.4193548 0.425 0.3208955 [[4]] X1 X2 X3 1 1.443548 1.425 1.238806 [[5]] X1 X2 X3 1 1.927419 1.983333 1.753731 Ugly! The values are right, but why didn't I get another 2D array back? Shouldn't the division in my inline function return a vector? Thanks, Greg
Try this: sweep(x, 2, as.numeric(x[1,]), FUN="/") On Thu, Jul 3, 2008 at 7:04 PM, Greg Kettler <gkettler@gmail.com> wrote:> Hi, > I'd like to normalize a dataset by dividing each row by the first row. > Very simple, right? > I tried this: > > > expt.fluor > X1 X2 X3 > 1 124 120 134 > 2 165 163 174 > 3 52 51 43 > 4 179 171 166 > 5 239 238 235 > > >first.row <- expt.fluor[1,] > > normed <- apply(expt.fluor, 1, function(r) {r / first.row}) > >normed > [[1]] > X1 X2 X3 > 1 1 1 1 > > [[2]] > X1 X2 X3 > 1 1.330645 1.358333 1.298507 > > [[3]] > X1 X2 X3 > 1 0.4193548 0.425 0.3208955 > > [[4]] > X1 X2 X3 > 1 1.443548 1.425 1.238806 > > [[5]] > X1 X2 X3 > 1 1.927419 1.983333 1.753731 > > Ugly! The values are right, but why didn't I get another 2D array > back? Shouldn't the division in my inline function return a vector? > > Thanks, > Greg > > ______________________________________________ > 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. >-- Henrique Dallazuanna Curitiba-Paraná-Brasil 25° 25' 40" S 49° 16' 22" O [[alternative HTML version deleted]]
on 07/03/2008 05:04 PM Greg Kettler wrote:> Hi, > I'd like to normalize a dataset by dividing each row by the first row. > Very simple, right? > I tried this: > >> expt.fluor > X1 X2 X3 > 1 124 120 134 > 2 165 163 174 > 3 52 51 43 > 4 179 171 166 > 5 239 238 235 > >> first.row <- expt.fluor[1,] >> normed <- apply(expt.fluor, 1, function(r) {r / first.row}) >> normed > [[1]] > X1 X2 X3 > 1 1 1 1 > > [[2]] > X1 X2 X3 > 1 1.330645 1.358333 1.298507 > > [[3]] > X1 X2 X3 > 1 0.4193548 0.425 0.3208955 > > [[4]] > X1 X2 X3 > 1 1.443548 1.425 1.238806 > > [[5]] > X1 X2 X3 > 1 1.927419 1.983333 1.753731 > > Ugly! The values are right, but why didn't I get another 2D array > back? Shouldn't the division in my inline function return a vector? > > Thanks, > GregMore than likely, expt.fluor is a data frame and not a matrix. Since a data frame is a list based object, you get a list returned when dividing by the first row, which is a data frame (not a vector) by itself. You could do this, using unlist(): > t(apply(expt.fluor, 1, function(x) x / unlist(expt.fluor[1, ]))) X1 X2 X3 1 1.0000000 1.000000 1.0000000 2 1.3306452 1.358333 1.2985075 3 0.4193548 0.425000 0.3208955 4 1.4435484 1.425000 1.2388060 5 1.9274194 1.983333 1.7537313 Alternatively, just coerce expt.fluor to a matrix first: expt.fluor <- as.matrix(expt.fluor) > t(apply(expt.fluor, 1, function(x) x / expt.fluor[1, ])) X1 X2 X3 1 1.0000000 1.000000 1.0000000 2 1.3306452 1.358333 1.2985075 3 0.4193548 0.425000 0.3208955 4 1.4435484 1.425000 1.2388060 5 1.9274194 1.983333 1.7537313 Of course, you could also do this, leaving expt.fluor as a data frame: > do.call(rbind, apply(expt.fluor, 1, function(x) x / expt.fluor[1, ])) X1 X2 X3 1 1.0000000 1.000000 1.0000000 2 1.3306452 1.358333 1.2985075 3 0.4193548 0.425000 0.3208955 4 1.4435484 1.425000 1.2388060 5 1.9274194 1.983333 1.7537313 You could also do the transpose first, which in effect does a coercion to a matrix: > apply(t(expt.fluor), 1, function(x) x / x[1]) X1 X2 X3 1 1.0000000 1.000000 1.0000000 2 1.3306452 1.358333 1.2985075 3 0.4193548 0.425000 0.3208955 4 1.4435484 1.425000 1.2388060 5 1.9274194 1.983333 1.7537313 Finally, use sapply() in a column-wise fashion: > sapply(expt.fluor, function(x) x / x[1]) X1 X2 X3 [1,] 1.0000000 1.000000 1.0000000 [2,] 1.3306452 1.358333 1.2985075 [3,] 0.4193548 0.425000 0.3208955 [4,] 1.4435484 1.425000 1.2388060 [5,] 1.9274194 1.983333 1.7537313 Which approach you take is predicated on various factors, including personal style, readability and what you will ultimately do with the result. My preference would be to use sapply() as in the final example. HTH, Marc Schwartz
This should work whether your data, x, is a data frame or a matrix: x / x[rep(1, nrow(x)),] On Thu, Jul 3, 2008 at 6:04 PM, Greg Kettler <gkettler at gmail.com> wrote:> Hi, > I'd like to normalize a dataset by dividing each row by the first row. > Very simple, right? > I tried this: > >> expt.fluor > X1 X2 X3 > 1 124 120 134 > 2 165 163 174 > 3 52 51 43 > 4 179 171 166 > 5 239 238 235 > >>first.row <- expt.fluor[1,] >> normed <- apply(expt.fluor, 1, function(r) {r / first.row}) >>normed > [[1]] > X1 X2 X3 > 1 1 1 1 > > [[2]] > X1 X2 X3 > 1 1.330645 1.358333 1.298507 > > [[3]] > X1 X2 X3 > 1 0.4193548 0.425 0.3208955 > > [[4]] > X1 X2 X3 > 1 1.443548 1.425 1.238806 > > [[5]] > X1 X2 X3 > 1 1.927419 1.983333 1.753731 > > Ugly! The values are right, but why didn't I get another 2D array > back? Shouldn't the division in my inline function return a vector? > > Thanks, > Greg > > ______________________________________________ > 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. >