eigenfoo
eigenfoo

Reputation: 229

Create a rolling list in R

Given a vector (column of a data frame), I'd like to create a rolling vector.

l = 0:10

Would return, (with a window of 3):

[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5] ...

Upvotes: 3

Views: 556

Answers (2)

G. Grothendieck
G. Grothendieck

Reputation: 270448

1) rollapply r is a 9x3 matrix each of whose rows is one of the list elements asked for and split turns that into a list of vectors. Although this gives what you asked for it may be that you just want to iterate over that list and in that case it might be easier to just replace c with whatever function you wanted to use in that iteration. e.g. rollapply(l, 3, sd)

library(zoo)
l <- 0:10 # test input
r <- rollapply(l, 3, c)
split(r, row(r))

giving:

$`1`
[1] 0 1 2

$`2`
[1] 1 2 3

$`3`
[1] 2 3 4

$`4`
[1] 3 4 5

$`5`
[1] 4 5 6

$`6`
[1] 5 6 7

$`7`
[1] 6 7 8

$`8`
[1] 7 8 9

$`9`
[1]  8  9 10

2) embed This could also be done using base R like this:

r <- embed(l, 3)[, 3:1]
split(r, row(r))

Upvotes: 6

Rage
Rage

Reputation: 323

You can use the following function (I am assuming you want the values to be sorted first. If not, just remove the line of code where I am using sort()) :

roll<-function(list,window){
  list<-sort(list,decreasing = FALSE)
  res<-vector(mode = "list")
  for(i in 1:(length(list) - window + 1)){
    res[[i]]<-list[i:(i + window - 1)]
  }
  return(res)
}

Enter your column/list values in the argument along with the window size you want and it should give you the desired output.

For example:

test<-0:10

roll(list = test,window = 3)

This results in the following output:

[[1]]
[1] 0 1 2

[[2]]
[1] 1 2 3

[[3]]
[1] 2 3 4

[[4]]
[1] 3 4 5

[[5]]
[1] 4 5 6

[[6]]
[1] 5 6 7

[[7]]
[1] 6 7 8

[[8]]
[1] 7 8 9

[[9]]
[1]  8  9 10

You can use this function for other cases and even change the window size as per your requirements.

Hope that helps!

Upvotes: 0

Related Questions