2

I believe my question is quite simple, but I can't manage to find the right answer.

In any given dataframe:

> data.frame(x0=c(1,2,3,4), x1=rnorm(4))
  x0         x1
1  1 -0.1868765
2  2 -0.2935534
3  3 -1.3934953
4  4  0.8165035

Imagine I'd like to take every two rows and repeat it by 2 times ending up with something like this:

> data.frame(x0=c(1,2,3,4), x1=rnorm(4))
  x0         x1
1  1 -0.1868765
2  2 -0.2935534
3  1 -0.1868765
4  2 -0.2935534
5  3 -1.3934953
6  4  0.8165035
7  3 -1.3934953
8  4  0.8165035


What is the easiest way to do this?

Thanks in advance!

Unai Vicente
  • 367
  • 3
  • 10

3 Answers3

3

You can create group of 2 rows and repeat it twice for each group, unlist the indices and subset.

set.seed(123)
df <- data.frame(x0=c(1,2,3,4), x1=rnorm(4))

inds <- seq(nrow(df))
df[unlist(tapply(inds, ceiling(inds/2), rep, 2)), ]

#    x0          x1
#1    1 -0.56047565
#2    2 -0.23017749
#1.1  1 -0.56047565
#2.1  2 -0.23017749
#3    3  1.55870831
#4    4  0.07050839
#3.1  3  1.55870831
#4.1  4  0.07050839
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
1

Actually, you could just do that using rep.

d[rep(seq(nrow(d)), each=2), ]
# x0          x1
# 1    1 -0.56047565
# 1.1  1 -0.56047565
# 2    2 -0.23017749
# 2.1  2 -0.23017749
# 3    3  1.55870831
# 3.1  3  1.55870831
# 4    4  0.07050839
# 4.1  4  0.07050839

Data:

d <- structure(list(x0 = c(1, 2, 3, 4), x1 = c(-0.560475646552213, 
-0.23017748948328, 1.55870831414912, 0.070508391424576)), class = "data.frame", row.names = c(NA, 
-4L))
jay.sf
  • 60,139
  • 8
  • 53
  • 110
  • 2
    I like this one. Though its not exactly what OP wants. He wants 1 and 2 repeated, then 3 and 4 etc. and not 1 repeated, 2 repeated etc. Not sure, if that would make a dfifference for him. – Dutschke Dec 18 '20 at 11:45
0

We can use uncount

library(dplyr)
library(tidyr)
df %>% 
   uncount(2) %>%
   as_tibble

-output

# A tibble: 8 x 2
#     x0      x1
#  <dbl>   <dbl>
#1     1 -0.560 
#2     1 -0.560 
#3     2 -0.230 
#4     2 -0.230 
#5     3  1.56  
#6     3  1.56  
#7     4  0.0705
#8     4  0.0705

data

set.seed(123)
df <- data.frame(x0=c(1,2,3,4), x1=rnorm(4))
akrun
  • 874,273
  • 37
  • 540
  • 662
  • Thanks akron! Out of curiosity, I see 2 is the parameter which estimates the row count, what about the repeat? what if i want to repeat these two rows, for instance, 5 times? This is, in fact, the question, in your proposal the result is not exactly what is wanted. – Unai Vicente Dec 19 '20 at 09:00
  • @UnaiVicente if you want to repeat 5 times, change the 2 to 5. Is that your question? – akrun Dec 19 '20 at 17:35
  • Nope, if you look carefully at my example, you'll see two different specifications are needed, your proposal only takes 1 into account. Therefore, it does not do what I was asking. Thanks though! – Unai Vicente Dec 20 '20 at 07:00