Eva
Eva

Reputation: 339

Repeat data frame with varying date column

How can I repeat a data frame with varying date column at the end? If I apply one of the previously recommended ways, all the columns get repeated. For example:

df<-data.frame(x1=c(1:3), x2=c('z','g','h'), x3=c( rep( as.Date("2011-07-31"), by=1, len=3)) )
n=2
do.call("rbind", replicate(n, df, simplify = FALSE))

   x1 x2        x3
1  1  z 2011-07-31
2  2  g 2011-07-31
3  3  h 2011-07-31
4  1  z 2011-07-31
5  2  g 2011-07-31
6  3  h 2011-07-31

Whereas what I need is:

  x1 x2         x3
1  1  z 2011-07-31
2  2  g 2011-07-31
3  3  h 2011-07-31
4  1  z 2011-08-01
5  2  g 2011-08-01
6  3  h 2011-08-01

Upvotes: 0

Views: 405

Answers (2)

lmo
lmo

Reputation: 38500

Here is another base R method that works for your example.

# save result
dat <- do.call("rbind", replicate(n, df, simplify = FALSE))

# update x3 variable
dat$x3 <- dat$x3 + cumsum(dat$x1 == 1) - 1

The logic is that we use a cumulative sum that is incremented every time x1 returns to its initial value (here 1). We subtract 1 from the result as we don't want to alter the first block.

this returns

dat
  x1 x2         x3
1  1  z 2011-07-31
2  2  g 2011-07-31
3  3  h 2011-07-31
4  1  z 2011-08-01
5  2  g 2011-08-01
6  3  h 2011-08-01

Using transform, this can be written

transform(dat, x3 = x3 + cumsum(x1 == 1) - 1)

As an alternative counting procedure, we could use seq_len together with rep like this

# update x3 variable
dat$x3 <- dat$x3 + rep(seq_len(n)-1L, each=nrow(df))

Upvotes: 0

Prasanna Nandakumar
Prasanna Nandakumar

Reputation: 4335

> n=2
> df1 <- df[rep(1:nrow(df), n),]
> transform(df1, x3=ave(x3, x1, FUN=function(x) x + 1:length(x) - 1L))
    x1 x2         x3
1    1  z 2011-07-31
2    2  g 2011-07-31
3    3  h 2011-07-31
1.1  1  z 2011-08-01
2.1  2  g 2011-08-01
3.1  3  h 2011-08-01

or

> library(dplyr)
> df1 <- df[rep(1:nrow(df), n),]
> df1 %>% group_by(x1,x2) %>% mutate(x3= x3 + 1:n() - 1L)

Upvotes: 2

Related Questions