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

Reply via email to