Following the title, for example, I want to get just the first even number in (1,4,5,2,7,45,8). I can do loop, I can use which(), but they seem not efficient enough. Do you have any better ideas?
Thank you!
Here's my first attempt with Rcpp. I don't really know C++, but this seems to work, and since it breaks after finding the first even number, and the explicit for loop runs in compiled code, it should be very fast.
> library(Rcpp)
> cppFunction('
+ int firstEven(IntegerVector x) {
+ int n = x.size();
+ for(int i = 0; i < n; ++i) {
+ if (x[i] % 2 == 0) {
+ return x[i];
+ }
+ }
+ }'
+ )
> firstEven(c(1,2,3,4))
[1] 2
>
It is definitely a naive solution (e.g., no check if there isn't an even number in the vector).
EDIT Results from timing the solutions for:
1) the vector approach: tst[tst %% 2 == 0][1]
2) firstEven (Rcpp)
3) for loop with break
4) match()
using two vectors, tst2 with first as even, tst with last as even:
tst <- c(rep(1, 10000000), 2)
tst2 <- c(2, rep(1, 10000000))
system.time results:
test time
1 for.tst 8.11
2 for.tst2 0.00
3 cpp.tst 0.05
4 cpp.tst2 0.05
5 vector.tst 0.47
6 vector.tst2 0.47
7 match.tst 0.61
8 match.tst2 0.61
For loop has best case and worst case, the other two are the same in both cases, but using the Rcpp library is much faster.
For loop with a break statement to stop searching list
for (i in c(1,4,5,2,7,45,8)) {
if (i %% 2 == 0) {
print(i);
break;
}
}
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