is it possible to use vector index in while function? - r

so i'm trying to create a fibonacci sequence and I found the following syntax which works
x <- 0
y <- 1
fib <- c()
while (x < 4000000 & y < 4000000){
x <- x + y
y <- x + y
fib <- c(fib, x, y)
}
However, this syntax only create the vector as long as the value of the x and y which is used in the calculation doesn't exceed 4,000,000. is it possible to makes the while refer to "if vector fib has less than let's say 100 element"?
thanks in advance

Making a very slight change to your code, use the length() function check the length (number of elements) of fib before each iteration of the while loop.
while(length(fib)<100){....}
This way you avoid creating a further variable to count the number of iterations, as in the other answers.
For what it's worth, this is how I would do it - a for loop is more appropriate as you have a set number of iterations
n <- 100
fib <- c(0,1)
for(i in 3:n){
fib[i] <- fib[i-2] + fib[i-1]
}

Here's another way to write the code -
fib <- numeric(100)
fib[1] <- 0
fib[2] <- 1
i <- 2
while (i < 100){
i = i + 1
fib[i] = fib[i-1] + fib[i-2]
}
Growing vector in a loop (fib = c(fib, x, y)) is inefficient so I have created a vector of fixed length (100) and then assigned the value to it. This also avoid creation of unnecessary temporary variables x and y.

Just define another variable for using inside the while loop and increase it by the length of the fib,
x <- 0
y <- 1
mylen <- 0 # new variable
fib <- c()
while (mylen<100){
x <- x + y
y <- x + y
fib = c(fib, x, y)
mylen <- length(fib)
}

Related

Remove a vector from another vector

I would like to remove from the vector wine below the vector b=c(1,0).
The result should be d=c(1,1,0).
library(gtools)
wine=c(1,1,1,0,0)
x=combinations(5,2,v=wine,set=FALSE,repeats.allowed=FALSE)
y=matrix(NA,nrow(x),3)
I want to find the complementary matrix y of x.
Thanks for your time.
The following uses a function I have posted here. The function finds where in y the vector x occurs returning an index vector into y.
First, get where b occurs in wine. Then the location is used to remove the found vector.
occurs <- function(x, y) {
m <- length(x)
n <- length(y)
candidate <- seq.int(length = n - m + 1L)
for (i in seq.int(length = m)) {
candidate <- candidate[x[i] == y[candidate + i - 1L]]
}
candidate
}
wine <- c(1,1,1,0,0)
b <- c(1,0)
i <- occurs(b, wine)
d <- wine[-(i + seq(b) - 1L)]
d
#[1] 1 1 0

For loop in r using summation

I have this,
sum(x^i)
with i being greater than or equal to 1.
How can I create a for loop in R for this summation?
In other words, how do I format this summation in R?
If both x and i are vectors you may use for loop as -
x <- 1:10
i <- 1:10
result <- 0
for(e in i) {
result <- result + sum(x^e)
}
result
If any of x or i goes to infinity, then the result would always be infinity.
For a fixed x and infinite n,
x <- 0.1 # You may change x
s <- 0
n <- 0
while(n < 100) { #If you want inf, let n >=0 then R will freeze recommend large number...
s <- s + x^(n)
n<-n+1
}
s

Is it possible to use vector math in R for a summation involving intervals?

Title's a little rough, open to suggestions to improve.
I'm trying to calculate time-average covariances for a 500 length vector.
This is the equation we're using
The result I'm hoping for is a vector with an entry for k from 0 to 500 (0 would just be the variance of the whole set).
I've started with something like this, but I know I'll need to reference the gap (i) in the first mean comparison as well:
x <- rnorm(500)
xMean <-mean(x)
i <- seq(1, 500)
dfGam <- data.frame(i)
dfGam$gamma <- (1/(500-dfGam$i))*(sum((x-xMean)*(x[-dfGam$i]-xMean)))
Is it possible to do this using vector math or will I need to use some sort of for loop?
Here's the for loop that I've come up with for the solution:
gamma_func <- function(input_vec) {
output_vec <- c()
input_mean <- mean(input_vec)
iter <- seq(1, length(input_vec)-1)
for(val in iter){
iter2 <- seq((val+1), length(input_vec))
gamma_sum <- 0
for(val2 in iter2){
gamma_sum <- gamma_sum + (input_vec[val2]-input_mean)*(input_vec[val2-val]-input_mean)
}
output_vec[val] <- (1/length(iter2))*gamma_sum
}
return(output_vec)
}
Thanks
Using data.table, mostly for the shift function to make x_{t - k}, you can do this:
library(data.table)
gammabar <- function(k, x){
xbar <- mean(x)
n <- length(x)
df <- data.table(xt = x, xtk = shift(x, k))[!is.na(xtk)]
df[, sum((xt - xbar)*(xtk - xbar))/n]
}
gammabar(k = 10, x)
# [1] -0.1553118
The filter [!is.na(xtk)] starts the sum at t = k + 1, because xtk will be NA for the first k indices due to being shifted by k.
Reproducible x
x <- c(0.376972124936433, 0.301548373935665, -1.0980231706536, -1.13040590360378,
-2.79653431987176, 0.720573498411587, 0.93912102300901, -0.229377746707471,
1.75913134696347, 0.117366786802848, -0.853122822287008, 0.909259181618213,
1.19637295955276, -0.371583903741348, -0.123260233287436, 1.80004311672545,
1.70399587729432, -3.03876460529759, -2.28897494991878, 0.0583034949929225,
2.17436525195634, 1.09818265352131, 0.318220322390854, -0.0731475581637693,
0.834268741278827, 0.198750636733429, 1.29784138432631, 0.936718306241348,
-0.147433193833294, 0.110431994640128, -0.812504663900505, -0.743702167768748,
1.09534507180741, 2.43537370755095, 0.38811846676708, 0.290627670295127,
-0.285598287083935, 0.0760147178373681, -0.560298603759627, 0.447188372143361,
0.908501134499943, -0.505059597708343, -0.301004012157305, -0.726035976548133,
-1.18007702699501, 0.253074712637114, -0.370711296884049, 0.0221795637601637,
0.660044122429767, 0.48879363533552)

R - When to add a break

I have an exercise that compares efficiency of loop functions.
I have function
banana <- function(x)
{d <- length(x)
xi <- x[1:(d-1)]
xnext <- x[2:d]
sum <- sum(100*(xnext-xi^2)^2 + (xi-1)^2)
y <- sum
return(y)
}
I want to re-write the above using a for loop (or any loop). I have so far
for (i in x){
n = length(x)
y <- 100*(x[i+1]-x[i]^2)^2 +(x[i]-1)^2
}
I want the function to stop at n-1 and having difficulty knowing where to add the break. Can someone help?
Thanks in advance,
Sean
You don't really have to add a break statement, you can just loop over all but the nth i.
[-length(x)] removes the last element from the sequence.
y <- 0
for (i in seq_along(x)[-length(x)]) {
y <- y + 100 * (x[i + 1] - x[i])^2 + (x[i] - 1)^2
}

Summing over a range of value in R (not using for loop)

How do you perform such summation in R?
sum_{i=1}^3 (x^2)
i=1 is lower bound
i=3 is upper bound
x^2 is the operation
So we will perform
1^2 + 2^2 + 3^2
Using standard loop:
tot <-0
for (x in 1:3) {
tot <- tot + x^2
}
First, I'll point out that to generate a vector containing the elements 1,2,3 you can do:
x <- 1:3
Secondly, R is a vectorised language - meaning if x is a vector and I do x + 5 it'll add 5 to each element of x for me without needing a for loop.
# Recalling that "x <- x + 5" is the same as
for ( i in 1:length(x) ) {
x[i] <- x[i] + 5
}
# try to do something that makes x squared, i.e. x == c(1,4,9).
Thirdly, look at ?sum, whereby sum(x) adds up all the elements in x.
the_answer <- sum( (1:3)^2 )
For-loops are so last century.

Resources