Re: [R] apply with a division

From: Gavin Simpson <gavin.simpson_at_ucl.ac.uk>
Date: Fri, 04 Jul 2008 08:43:04 +0100

[Sorry, I seem to have misplaced the original posting, hence I'll reply here as I haven't seen this solution mentioned yet]

See ?sweep - this is very general function for this sort of operation. Note that mat is the OP's data as a matrix, not a data frame. This doesn't work if mat is a data frame.

> mat

     [,1] [,2] [,3]

[1,]  124  120  134
[2,]  165  163  174
[3,]   52   51   43
[4,]  179  171  166
[5,]  239  238  235

> sweep(mat, 2, mat[1,], "/")
[,1] [,2] [,3] [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

HTH G

On Thu, 2008-07-03 at 20:39 -0500, Marc Schwartz wrote:
> 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,
> > Greg
>
> More 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
>
> ______________________________________________
> 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.



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. Received on Fri 04 Jul 2008 - 07:49:54 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Fri 04 Jul 2008 - 10:31:31 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-help. Please read the posting guide before posting to the list.

list of date sections of archive