I was writing up notes to compare apply() and sweep() and discovered the following strange differences. In order the generate the same result, sweep() needs MARGIN = 1 while apply wants MARGIN = 2. Also the argument specifying the matrix is uppercase X in apply() but lowercase in sweep().
my.matrix <- matrix(seq(1,9,1), nrow=3)
row.sums <- rowSums(my.matrix)
apply.matrix <- apply(X = my.matrix, MARGIN = 2, FUN = function (x) x/row.sums)
sweep.matrix <- sweep(x = my.matrix, MARGIN = 1, STATS = rowSums(my.matrix), FUN="/")
apply.matrix - sweep.matrix ##yup same matrix
Isn't sweep() an "apply-type" function? Is this just another R quirk or have I lost my mind?
Note that for apply
,
If each call to ‘FUN’ returns a vector of length ‘n’, then ‘apply’ returns an array of dimension ‘c(n, dim(X)[MARGIN])’ if ‘n > 1’
In your example, MARGIN
can (and should) be set to 1
in both cases; but the returned value from apply
should be transposed. This is easiest to see if the original matrix is not square:
my.matrix <- matrix(seq(1,12,1), nrow=4)
apply.matrix <- t(apply(X = my.matrix, MARGIN = 1, FUN = function(x) x/sum(x)))
sweep.matrix <- sweep(x = my.matrix, MARGIN = 1, STATS = rowSums(my.matrix), FUN="/")
all.equal(apply.matrix, sweep.matrix)
# [1] TRUE
Also see this answer to Can you implement 'sweep' using apply in R?, which says very much the same thing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With