Q:

apply() vs. sweep() in R

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?

A:

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.

