Irene232545
Irene232545

Reputation: 31

Create a geometric sequence

I want to make a dataframe using a simple formula. the first number I want to be '5' and the next one '5 * 2=10' and the next one '10 * 2=20' for 10 times.

    out
1   5
2   10
3   20
4   40
5   80
6   160
7   320
8   640
9   1280
10  2560

I tried:

b=5
for(i in 1:10){
  b[i] <- b[i]*2
  a <- data.frame(b[i])
}

now dataframe a has 1 obs. and 1 variable but I want a dataframe with 10 obs. and 1 variable. Can someone help me with this problem?

And what to do if the max is 320? like this:

    out
1   5
2   10
3   20
4   40
5   80
6   160
7   320
8   320
9   320
10  320

Upvotes: 1

Views: 253

Answers (2)

AnilGoyal
AnilGoyal

Reputation: 26218

Simply as @henrik has suggested

5*2^(0:9)

 [1]    5   10   20   40   80  160  320  640 1280 2560

pmin(5*2^(0:9), 320)
 [1]   5  10  20  40  80 160 320 320 320 320

For edited part

data.frame(out = pmin(320, Reduce(f = function(.x, .y) .x *2, x = 1:9, init = 5, accumulate = T)))

   out
1    5
2   10
3   20
4   40
5   80
6  160
7  320
8  320
9  320
10 320

Earlier answer

You may do something like this in purrr or in base r. Basically 1:9 means nine iterations plus one for initial value giving us 10 accumulations.

accumulate(1:9, .init = 5, ~.x *2) %>%
  as.data.frame() %>%
  setNames('out')

    out
1     5
2    10
3    20
4    40
5    80
6   160
7   320
8   640
9  1280
10 2560

or in baseR

data.frame(out = Reduce(f = function(.x, .y){.x * 2}, x = 1:9, init = 5, accumulate = T))

    out
1     5
2    10
3    20
4    40
5    80
6   160
7   320
8   640
9  1280
10 2560

Upvotes: 2

Anoushiravan R
Anoushiravan R

Reputation: 21908

Updated

Based on your new requirements I modified the solution. It's a little bit specific for this case only. However, I defined argument l to determine the number of rows of the subsequent data frame and also max_value to determine from which index on we have repetition:

my_df <- function(l = 10, max_value = n) {
  out <- c(5, rep(NA, l - 1))
  
  for(i in 2:length(out)) {
    out[[i]] <- out[[i-1]] * 2
  }
  
  if(max_value %in% out) {
    start <- which(out == max_value)
    out[start:length(out)] <- max_value
  }
  data.frame(out)
}

my_df(max = 320)  

   out
1    5
2   10
3   20
4   40
5   80
6  160
7  320
8  320
9  320
10 320

Alternative

out <- c(5, rep(NA, 9))
for(i in 2:length(out)) {
  out[[i]] <- if(out[[i-1]] * 2 > 320){
    320 
  } else { out[[i-1]] * 2}
}
out

 [1]   5  10  20  40  80 160 320 320 320 320

Upvotes: 1

Related Questions