Repeating sequence R

Viewed 179

I'm trying to repeat the sequence 0, 1, 2 down the rows of my data frame with the following:

x <- c(1, 2, 3, 4, 5, 6, 7)
y <- c(1, 2, 3, 4, 5, 6, 7)

df <- cbind(x, y)
df <- as.data.frame(df)

df$W <- rep(0:2, nrow(df)/3)
df$W <- rep(0:1, nrow(df)/2)

Which doesn't work because the replacement has 6 rows, data has 7. I feel like there has to be a simpler solution to this. I just want it start the next sequence but stop when it finishes at the last row of the data frame. So W would just be 0, 1, 2, 0, 1, 2, 0. And for the other option with rep(0:1) it would be 0, 1, 0, 1, 0, 1, 0

3 Answers

Use the length.out option

rep(0:2, length.out = nrow(df))
#[1] 0 1 2 0 1 2 0
rep(0:1, length.out = nrow(df))
#[1] 0 1 0 1 0 1 0

You can use modular arithmetic.

Here are two impelemntations using data.table and dplyr

## data.table
library(data.table)

setDT( df )[, w := (.I - 1 ) %% 3][]
## .I is what data.table uses to store 'row number'
## think of it as the row 'index'

#    x y w
# 1: 1 1 0
# 2: 2 2 1
# 3: 3 3 2
# 4: 4 4 0
# 5: 5 5 1
# 6: 6 6 2
# 7: 7 7 0

## dplyr
library(dplyr)

df %>%
  mutate(w = (row_number() - 1) %% 3)

#   x y w
# 1 1 1 0
# 2 2 2 1
# 3 3 3 2
# 4 4 4 0
# 5 5 5 1
# 6 6 6 2
# 7 7 7 0

For the 0, 1, sequence use %% 2

With base R, we can use %% like below (but the most efficient solution is by rep as given by @akrun)

df$W <- (seq(nrow(df))-1)%%3
Related