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.
sapply help
6 messages · Philippe Massicotte, Ernest Adrogué, William Dunlap +1 more
3-02-2012, 08:37 (-0800); Filoche escriu:
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
This does that:
sapply(1:5, function(i) sum(M[,i] < v[i]))
[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.
Cheers, Ernest
Le vendredi 03 f?vrier 2012 ? 18:27 +0100, Ernest Adrogu? a ?crit :
3-02-2012, 08:37 (-0800); Filoche escriu:
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
This does that:
sapply(1:5, function(i) sum(M[,i] < v[i]))
[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.
Though in your case, I think there are shorter solutions. For example:
colSums(t(apply(M, 1, "<", v)))
[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
Thank you sire. You explained it very well. This give ma a good point to start using sapply more frequently. Cordially, Phil -- View this message in context: http://r.789695.n4.nabble.com/sapply-help-tp4355092p4355376.html Sent from the R help mailing list archive at Nabble.com.
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
-----Original Message----- From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of Milan Bouchet- Valat Sent: Friday, February 03, 2012 10:17 AM To: Ernest Adrogu? Cc: r-help at r-project.org Subject: Re: [R] sapply help Le vendredi 03 f?vrier 2012 ? 18:27 +0100, Ernest Adrogu? a ?crit :
3-02-2012, 08:37 (-0800); Filoche escriu:
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
This does that:
sapply(1:5, function(i) sum(M[,i] < v[i]))
[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.
Though in your case, I think there are shorter solutions. For example:
colSums(t(apply(M, 1, "<", v)))
[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
______________________________________________ R-help at 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.
Le vendredi 03 f?vrier 2012 ? 18:51 +0000, William Dunlap a ?crit :
Instead of colSums(t(aMatrix)), why not the more direct rowSums(aMatrix)?
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.