For Loop in R - Need Assistance - r

I'm struggling with For Loops and hope that someone can assist me. I need use a loop in R to determine the value of Σ25i=1i2
I'm new to learning R, and I can't seem to figure this out.
Thank you for your help.

With a for loop you can do :
n <- 25
vec <- numeric(n)
for(i in seq_len(n)) vec[i] <- i^2
sum(vec)
#[1] 5525
seq_len creates a sequence from 1 to n and for each value we square the number and store it in vec at ith positon.
However, you can do this without for loop directly.
sum(seq_len(n)^2)
#[1] 5525

A faster way for calculation with larger n is to apply the math formula
res <- n*(n+1)*(2n+1)/6

R is vectorized, therefore a loop is not the natural way of doing this computation. Better to perform the sum this way:
sum(seq(1, 25, 1)^2)
#5525

Related

In R, faster way than for loop or apply

For these two matrices, I want to find the product of the matrix X and the row of Q and apply ifelse function to see if the product is greater than zero.
n1=1000, m=10000
X=cbind(rnorm(n1),rbinom(n1))
Q=matrix(rnorm(2*m), ncol=2)
To do this, I tried for loop and apply function in the following.
D=10000
ind_beta=matrix(0,n1,D)
for (l in 1:D){
ind[,l]=as.vector(ifelse(X%*%Q[l,]>=0,1,0))
}
and
ind=apply(Q,1,function(x){ifelse(X%*%Q>=0,1,0)})
Both codes give the same result, but it is really time consuming.
Is there any way to make this fast? Thanks in advance.
How about:
Make data (reproducibly):
set.seed(101)
n1=1000; m=10000
X=cbind(rnorm(n1),rbinom(n1,size=1,prob=0.6))
Q=matrix(rnorm(2*m), ncol=2)
Your way takes about 2.5 seconds:
system.time(ind <- apply(Q,1,function(x){ifelse(X%*%x>=0,1,0)}))
This takes about 0.3 seconds:
system.time({
XQ <- X %*% t(Q)
ind2 <- matrix(as.numeric(XQ>=0),nrow(XQ))
})
Results match:
all.equal(ind,ind2) ## TRUE

Vectorize loop in R

I have some array named P_Array with 100,000 data points and need to calculate the first order autocorrelation for subintervalls of length 100, i.e. from 1:100 and 2:101 etc. I've written a loop which works just fine, but is very slow.
Tf <- 100000
acf_Array <- rep(0, length.out = Tf-100)
for (t in 1:(Tf-100)){
acf_Array[t] <- acf(P_Array[t:(t+100)])$acf[2]
}
My idea was to use something like
acf_Array[1:(Tf-100)] <- acf(P_Array[(1:(Tf-100)):(101:Tf)])$acf[2]
which, however, does not work. Any suggestions?
Edit
I think this will do the trick
for (t in 1:(Tf-100)){
acf_Array[t] <- cor(P_Array[t:(t+98)], P_Array[(t+1):(t+99)])
}
To answer the specific question on vectorising the for loop, this is my answer:
acf_Array <- sapply(1:Tf-100, function(x) acf(P_Array[x:x+100])$acf[2])
But as mentioned in the comments the speed limiting bit is probably the acf function.

How to make a matrix from a given vector by using for loop

I am trying to make a $n\times 4$ matrix by retrieving the n-th four elements in a given vector. Since I am new to R, don't know how to use loop functions properly.
My code is like
x<-runif(150,-2,2)
x1<-c(0,0,0,0,x)
for (i in 0:150)
{ai<-x1[1+i,4+i]
}
However, I got: Error in x1[1 + i, 4 + i] : incorrect number of dimensions.
I also want to combine these ai into a matrix, and each ai will be the i+1-th row of the matrix. Guess I should use the cbind function?
Any help will be appreciated. Thanks in advance.
You can do this directly with the matrix command:
x <- 1:36
xmat<-matrix(x,nr=9,byrow=TRUE)
May be this helps:
n <- length(x1)-1
res <- sapply((4:n)-3, function(i) x1[(i+3):i])
dim(res)
#[1] 4 150

How to avoid a loop here in 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".

Applying a function to a random sample of vector elements

I have been learning R for the past few days, and want to find out whether the problem below can be solved in a better manner (compacter code perhaps) than my solution.
Problem: A vector V of N (~ 1000) numeric elements, needs to be transformed in the following way.
Choose M (~ 100) elements at random.
Replace each such element x with f(x).
My Solution: for (i in sample(1:N, M)) V[i] = f(V[i])
Edit: The function f takes as input a single numeric value, and also outputs a single numeric value. Something like: f <- function (x) x^3 + 2
Edit: Thanks for everyone's contributions! I now understand the power of vectorized functions. :)
How about this
i <- sample(1:N, M)
V[i] <- f(V[i])
No need for loop since [<- is a vectorized function. See ?"[<-" to get further details on that.
It depends on the type of your function. If f is vectorised then
V <- f(V) # V is a vector with random numbers
will do the job. If f takes and returns a single value then:
V <- sapply(V, f)
Thankfully, in R most of the function are vectorised, so the first approach would work quite often.

Resources