How to avoid a loop here in R? - r

In my R program I have a "for" loop of the following form:
for(i in 1:I)
{
res[i] <- a[i:I] %*% b[i:I]
}
where res, a and b are vectors of length I.
Is there any straightforward way to avoid this loop and calculate res directly? If so, would that be more efficient?
Thanks in advance!

This is the "reverse cumsum" of a*b
rev(cumsum(rev(a) * rev(b)))

So long as res is already of length I, the for loop isn't "incorrect" and the apply solutions will not really be any faster. However, using apply can be more succinct...(if potentially less readable)
Something like this:
res <- sapply(seq_along(a), function(i) a[i:I] %*% b[i:I])
should work as a one-liner.
Expanding on my first sentence. While using the inherent vectorization available in R is very handy and often the fastest way to go, it isn't always critical to avoid for loops. Underneath, the apply family determines the size of the output and pre-allocates it before "looping".

Related

How can I create a vector by only using for loop? (vector is specified in the body)

(1,2,2,3,3,3,4,4,4,4,...,n,...,n)
I want to make the above vector by for loop, but not using rep function or the other functions. This may not be good question to ask in stackoverflow, but since I am a newbie for R, I dare ask here to be helped.
(You can suppose the length of the vector is 10)
With a for loop, it can be done with
n <- 10
out <- c()
for(i in seq_len(n)){
for(j in seq_len(i)) {
out <- c(out, i)
}
}
In R, otherwise, this can be done as
rep(seq_len(n), seq_len(n))
I have been beaten by #akrun by seconds, even so I'd like to give you a few hints if using rep would have been possible which may help you with R in general. (Without rep usage, just look at #akrun)
Short answer using rep
rep(1:n, 1:n)
Long Answer using rep
Before posting a question you should try to develop your own solutions and share them.
Trying googling a bit and sharing what you already found is usually good as well. Please, have a look at "help/how-to-ask"
Let's try to do it together.
First of all, we should try to have a look at official sources:
R-project "getting help", here you can see the standard way to get a function's documentation is just typing ?func_name in your R console
R-project "official manuals" offer a good introduction to R. Try looking at the first topic, "An Introduction to R"
From the previous two (and other sources as well) you will find two interesting functions:
: operator: it can be used to generate a sequence of integers from a to b like a:b. Typing 1:3, for instance, gives you the 1, 2, 3 vector
rep(x, t) is a function which can be used to replicate the item(s) x t times.
You also need to know R is "vector-oriented", that is it applies functions over vectors without you typing explicits loops.
For instance, if you call repl(1:3, 2), it's (almost) equivalent to running:
for(i in 1:3)
rep(i, 2)
By combining the previous two functions and the notion R is "vector-oriented", you get the rep(1:n, 1:n) solution.
I am not sure why you don't want to use rep, but here is a method of not using it or any functions similar to rep within the loop.
`for (i in 1:10){
a<-NA
a[1:i] <- i
if (i==1){b<-a}
else if (i >1){b <- c(b,a)}
assign("OutputVector",b,envir = .GlobalEnv)
}`
`OutputVector`
Going for an n of ten seemed subjective so I just did the loop for numbers 1 through 10 and you can take the first 10 numbers in the vector if you want. OutputVector[1:10]
You can do this with a single loop, though it's a while rather than a for
n <- 10
x <- 1;
i <- 2;
while(i <= n)
{
x <- c(x, 1/i);
if(sum(x) %% 1 == 0) i = i + 1;
}
1/x

In R, what's the most idiomatic way to find the maximal value of a vector before a position?

From a numeric vector, I want to obtain a vector of the same length containing the maximal value found until the position as value.
I can obtain such result using a for loop as in the example (or using Rcpp for faster results), but I was wondering if there was a more idiomatic way to do it or if a built-in function did already exist in some package.
vector <- c(1L,2L,3L,2L,2L,4L,5L,1L,2L,3L,6L,7L,3L)
initialMax <- -1L
result <- vector
N <- length(vector)
for(i in 1:N){
if(vector[i]>initialMax){
result[i:N] <- vector[i]
initialMax <- vector[i]
}
}
Not really sure what you exactly want. But here's my shot.
This gives you a list() with the max values going from beginning to end.
I think using list() and therefore lapply should bring you into an idiomatic direction using R.
Using the pipe from package magrittr here. Not idiomatic but makes things a whole lot easier.
seq_along(vector) %>% lapply(function(N)return(max(vector[1:N],na.rm=T)))

Which function inside a loop is more efficient (ncol/nrow() or dim())

In an exercise attempt I am trying to create a multiplication table using a for loop. I am new to programming and R is my first language that I learn, so I would like to know which functions inside loops are faster and more efficient. For now, I am not using methods of the apply family because I think that understanding of basic functions like the loops is important.
Here are two ways that I use to create a multiplicaton table:
Using dim() function:
mtx <- matrix(nrow=10, ncol=10)
for(i in 1:dim(mtx)[1]){
for(j in 1:dim(mtx)[2]){
mtx[i,j] <- i*j
}
}
Using ncol/nrow() function:
mtx <- matrix(nrow=10, ncol=10)
for(i in 1:ncol(mtx)){
for(j in 1:nrow(mtx)){
mtx[i,j] <- i*j
}
}
Which way is more efficient and generaly better to use?
Thank you
If you use the functions like you do in your example, the difference is really neglectable. This is because the functions get called only once per loop definition (and not every loop iteration!)
I would definitely prefer ncol/nrow because its much easier too read than dim(x)[1].
That being said, if you just go for the timings, the dim function is faster than ncol/nrow. If you look at the source code, you can see that ncol is implemented as
function (x)
dim(x)[2L]
which means that ncol calls dim and is therefore marginally slower.
If you really want to save some speed with big matrices I would suggest to create the loop vectors beforehand like this:
rows <- 1:nrow(mtx)
cols <- 1:ncols(mtx)
for (i in rows) {
for (j in cols) {
mtx[i, j] <- i * j
}
}

replacing loops when comparing multidimensional arrays

I am working with multi-dimensional arrays, and making comparisons for each element. So far, I have been using loops, but I was wondering how I could use apply(or another better function to avoid the loops). I am not sure ..I tried several ways, but it is not working fine.
Let's say the following example, where I compute the 95 percentile for the elements of the 3-dimension, and then I make a comparison:
m <- array(1:30, c(5,4,3))
mp <- apply(m,1:2,quantile,probs=c(.95),na.rm=TRUE)
temp <- array(dim=dim(m))
for(i in 1:5){
for(j in 1:4){
temp[i,j,] <- m[i,j,]>mp[i,j]
}
}
I don't know if apply can be used here(I read some posts but still not sure), is there any other way to avoid the loops??
Thanks in advance!
You can use vectorization and assigning dimensions after the evaluation of your condition:
array(as.vector(m)>as.vector(mp),dim(m))

Avoid nested for loops when summing over matrix indices

I have a fairly simply computation I need to do, but I cannot figure out how to do it in a way that is even close to efficient. I have a large nxn matrix, and I need to compute the following:
I'm still fairly inexperienced at coding, and so the only way that comes to my mind is to do the straightforward thing and use 3 for loops to move across the indexes:
sum=0
for(i in 1:n)
{
for(j in 1:n)
{
for(k in 1:n)
{
sum = sum + A[i,j]*A[j,k]
}
}
}
Needless to say, for any decent size matrix this takes forever to run. I know there must be a better, more efficient way to do this, but I cannot figure it out.
If you don't consider the k and i sums, you can realise that you are just doing the matrix product of A with itself. Such product in R is obtained through the %*% operator. After calculating this matrix, you just need to sum all the elements together:
sum(A %*% A)
should give the result you are seeking.

Resources