tkvn
tkvn

Reputation: 85

Changing every set of 5 rows in R

I have a dataframe that looks like this:

df$a <- 1:20
df$b <- 2:21
df$c <- 3:22
df <- as.data.frame(df)

> df
    a  b  c
1   1  2  3
2   2  3  4
3   3  4  5
4   4  5  6
5   5  6  7
6   6  7  8
7   7  8  9
8   8  9 10
9   9 10 11
10 10 11 12
11 11 12 13
12 12 13 14
13 13 14 15
14 14 15 16
15 15 16 17
16 16 17 18
17 17 18 19
18 18 19 20
19 19 20 21
20 20 21 22

I would like to add another column to the data frame (df$d) so that every 5 rows (df$d[seq(1, nrow(df), 4)]) would take the value of the start of the respective row in the first column: df$a.

I have tried the manual way, but was wondering if there is a for loop or shorter way that can do this easily. I'm new to R, so I apologize if this seems trivial to some people.

"Manual" way:

df$d[1:5] <- df$a[1]
df$d[6:10] <- df$a[6]
df$d[11:15] <- df$a[11]
df$d[16:20] <- df$a[16]

>df
    a  b  c  d
1   1  2  3  1
2   2  3  4  1
3   3  4  5  1
4   4  5  6  1
5   5  6  7  1
6   6  7  8  6
7   7  8  9  6
8   8  9 10  6
9   9 10 11  6
10 10 11 12  6
11 11 12 13 11
12 12 13 14 11
13 13 14 15 11
14 14 15 16 11
15 15 16 17 11
16 16 17 18 16
17 17 18 19 16
18 18 19 20 16
19 19 20 21 16
20 20 21 22 16

I have tried

for (i in 1:nrow(df))
{df$d[i:(i+4)] <- df$a[seq(1, nrow(df), 4)]}  

But this is not going the way I want it to. What am I doing wrong?

Upvotes: 1

Views: 101

Answers (3)

IRTFM
IRTFM

Reputation: 263342

I'd use logical indexing after initializing to NA

 df$d <- NA
 df$d <- rep(df$a[ c(TRUE, rep(FALSE,4)) ], each=5)
 df
#--------
    a  b  c  d
1   1  2  3  1
2   2  3  4  1
3   3  4  5  1
4   4  5  6  1
5   5  6  7  1
6   6  7  8  6
7   7  8  9  6
8   8  9 10  6
9   9 10 11  6
10 10 11 12  6
11 11 12 13 11
12 12 13 14 11
13 13 14 15 11
14 14 15 16 11
15 15 16 17 11
16 16 17 18 16
17 17 18 19 16
18 18 19 20 16
19 19 20 21 16
20 20 21 22 16

Upvotes: 1

eddi
eddi

Reputation: 49448

And here's a data.table solution:

library(data.table)
dt = data.table(df)

dt[, d := a[1], by = (seq_len(nrow(dt))-1) %/% 5]

Upvotes: 1

Frank
Frank

Reputation: 66819

This should work:

df$d <- rep(df$a[seq(1,nrow(df),5)],each=5)

Upvotes: 2

Related Questions