Skip to content

sapply help

6 messages · Philippe Massicotte, Ernest Adrogué, William Dunlap +1 more

#
Hi every one.

I'm learning how to use sapply (and other function of this family).

Here's what I'm trying to do.

I have a vector of lets say 5 elements. I also have a matrix of nX5. I would
like to know how many element by column are inferior to each element of my
vector.

On this example:
v = c(1:5)
M = matrix(3,2,5)

I would like to have a vector at the end which give me

0 0 0 2 2

because in my matrix M, there's 2 row at my columns 4 and 5 that have number
< than values 4 and 5 respectively.

This is pretty simple to do with a loop, but I would like to know how to do
it with sapply.

I hope I have been clear enough.
Tx in advance.

Phil

 



--
View this message in context: http://r.789695.n4.nabble.com/sapply-help-tp4355092p4355092.html
Sent from the R help mailing list archive at Nabble.com.
#
3-02-2012, 08:37 (-0800); Filoche escriu:
This does that:
[1] 0 0 0 2 2

Basically, it's like a loop where at each iteration the function is
called with one element of the vector 1:5 as argument, so what this
really does is

sum(M[,1] < v[1]))
sum(M[,2] < v[2]))
...

and then the results are put all together in a vector.
#
Le vendredi 03 f?vrier 2012 ? 18:27 +0100, Ernest Adrogu? a ?crit :
Though in your case, I think there are shorter solutions. For example:
[1] 0 0 0 2 2

apply() is more suited to matrices. Here, it takes each row separately,
and compares it with v. Then, you can just sum the result to count the
number of cases that fulfill the condition.


Cheers
#
Instead of colSums(t(aMatrix)), why not the more
direct rowSums(aMatrix)?

If time is an issue (which it won't be unless
the number of columns of M is big), compare:
  > M <- matrix(2e5:1, nrow=2)
  > v <- 1:ncol(M)
  > system.time(z1 <- sapply(seq_along(v), function(i) sum(M[,i] < v[i])))
     user  system elapsed
    0.532   0.000   0.532
  > system.time(z2 <- colSums(t(apply(M, 1, "<", v))))
     user  system elapsed
    0.004   0.000   0.006
  > system.time(z3 <- rowSums(apply(M, 1, "<", v)))
     user  system elapsed
    0.008   0.000   0.005
  > system.time(z4 <- colSums(M < matrix(v, nrow=nrow(M), ncol=ncol(M), byrow=TRUE)))
     user  system elapsed
    0.000   0.000   0.002
  > isTRUE(all.equal(z1, z2)) && isTRUE(all.equal(z1,z3)) && isTRUE(all.equal(z1,z4))
  [1] TRUE

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com
#
Le vendredi 03 f?vrier 2012 ? 18:51 +0000, William Dunlap a ?crit :
Because I felt it was more didactic. The question was about counting
occurrences per column, so using rowSums() could be a little confusing
without an explanation.

Of course, your solution is faster and cleaner.