[R] apply with a division

Gavin Simpson gavin.simpson at ucl.ac.uk
Fri Jul 4 09:43:04 CEST 2008


[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.



More information about the R-help mailing list