2

I have a dataset with grouped observations per row. However, I would like to expand each row observation from a single observation per replicate to a set number (in this case "20" observations each).

In the attached picture, enter image description here

Each replicate is a row. I would like to expand each row into 20. So "wellA" for "LS x SB" becomes expands to 20 of the same line. As a bonus, I would also like to make a new column called "Replicate2" that numerically lists 1 to 20 to reflect these 20 new rows per replicate.

The idea would to then add the survival status per individual (reflected in the new columns "Status" and "Event").

I think the "expand" function in tidyr has potential but can't figure out how to just add a fixed number per replicate. Using the "Alive" column is adding a variable number of observations.

expand<-DF %>% expand(nesting(Date, Time, Cumulative.hrs, Timepoint, Treatment, Boat, Parentage, Well, Mom, Dad, Cone, NumParents, Parents), Alive)

Any help appreciated!

2 Answers2

1

In base R, we can use rep to repeat rows and transform to add new columns

n <- 20
transform(df[rep(seq_len(nrow(df)), each = n), ], Replicate = 1:n, row.names = NULL)

Using a reproducible example with n = 3

df <- data.frame(a = 1:3, b = 4:6, c = 7:9)
n <- 3
transform(df[rep(seq_len(nrow(df)), each = n), ], Replicate = 1:n, row.names = NULL)

#  a b c Replicate2
#1 1 4 7         1
#2 1 4 7         2
#3 1 4 7         3
#4 2 5 8         1
#5 2 5 8         2
#6 2 5 8         3
#7 3 6 9         1
#8 3 6 9         2
#9 3 6 9         3

Using dplyr we can use slice to repeat rows and mutate to add new column.

library(dplyr)

df %>%
  slice(rep(seq_len(n()), each = n)) %>%
  mutate(Replicate2 = rep(seq_len(n), n))
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
1

Do a cross join between your existing data and the numbers 1:20.

tidyr::crossing(DF, replicate2 = 1:20)

If you want to add additional columns, use mutate:

... %>% mutate(status = 1, event = FALSE)
Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294