Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

apply() vs. sweep() in R

Tags:

r

row

apply

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?

like image 853
Mark R Avatar asked Sep 14 '25 16:09

Mark R


1 Answers

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.

like image 155
Weihuang Wong Avatar answered Sep 16 '25 07:09

Weihuang Wong