Reputation: 389
My data looks like this:
das <- data.frame(val=1:3,
beginning =c(10,20,40),
end=c(20,40,51))
val beginning end
1 1 10 20
2 2 20 40
3 3 40 51
I want to break each row to 3 rows by dividing the beginning to end to equal parts. like this
Expected output
> das
val beginning end
1 1 10 13
2 2 13 16
3 3 16 20
4 4 20 27
5 5 27 34
6 6 34 40
7 7 40 44
8 8 44 48
9 9 48 51
I came across similar questions here, but most of them are w.r.t to date range.
Upvotes: 2
Views: 188
Reputation: 12819
n_intervals <- 3
rows <- split(das, seq_len(nrow(das)))
res <- do.call(rbind, lapply(rows, function(row) {
timesplits <- seq(from = row$beginning,
to = row$end,
length.out = n_intervals + 1)
data.frame(beginning = head(timesplits, -1),
end = tail(timesplits, -1))
}))
res$val <- seq_len(nrow(res))
#> beginning end val
#> 1.1 10.00000 13.33333 1
#> 1.2 13.33333 16.66667 2
#> 1.3 16.66667 20.00000 3
#> 2.1 20.00000 26.66667 4
#> 2.2 26.66667 33.33333 5
#> 2.3 33.33333 40.00000 6
#> 3.1 40.00000 43.66667 7
#> 3.2 43.66667 47.33333 8
#> 3.3 47.33333 51.00000 9
Upvotes: 1
Reputation: 35554
You can use uncount()
in tidyr
and then calculate the increment of each val
.
library(dplyr)
library(tidyr)
das %>%
uncount(3) %>%
mutate(beginning = beginning + round((end - beginning)/3) * 0:2,
end = lead(beginning, default = last(end)))
# val beginning end
# 1 1 10 13
# 2 1 13 16
# 3 1 16 20
# 4 2 20 27
# 5 2 27 34
# 6 2 34 40
# 7 3 40 44
# 8 3 44 48
# 9 3 48 51
Upvotes: 3