1
df <- data.frame(
  date = rep("2020-01-01", times = 10),
  letter = LETTERS[1:10],
  values = c(10, 1, 2, 5, 2, 1, 7, 4, 5, 8)
)

I would like to get the data frame unfolded haveng one row for every letter and every value of 1 if it is > 1.

date letter value 2020-01-01 A 1 -,-,- 2020-01-01 J 1

2 Answers2

1

You could do that with uncount:

tidyr::uncount(df, values)

Or if you want to keep the values column:

tidyr::uncount(df, values, .remove = FALSE)
arg0naut91
  • 14,574
  • 2
  • 17
  • 38
  • Great shortcut but code will be slower as it just used `rep` inside, check `tidyr::uncount` in console – Clemsang Apr 01 '20 at 13:37
  • Thanks! As for the benchmark, I've quickly checked on 100k rows and they look pretty similar. Yes `base` is faster but likely you wouldn't notice it. – arg0naut91 Apr 01 '20 at 13:46
  • 1
    Totally agree, just to precise that `uncount` is only a wrapper of `base` – Clemsang Apr 01 '20 at 13:50
0

You can use rep in base R:

expand <- df[rep(1:nrow(df), df$values),]
expand$values <- 1
head(expand)
          date letter values
1   2020-01-01      A      1
1.1 2020-01-01      A      1
1.2 2020-01-01      A      1
1.3 2020-01-01      A      1
1.4 2020-01-01      A      1
1.5 2020-01-01      A      1
Clemsang
  • 5,053
  • 3
  • 23
  • 41