Reputation: 493
I have a data set where each record has an interval, and I'd like to have the same information but as a set of discrete values within that interval instead.
Example: Input data frame
start end val
1 2 4 a
2 2 5 b
3 1 3 c
Output data frame
time val
1 2 a
2 3 a
3 4 a
4 2 b
5 3 b
6 4 b
7 5 b
8 1 c
9 2 c
10 3 c
What's a good way to accomplish that sort of transformation? Additionally, the val column could be multiple columns to repeat in the same pattern.
Upvotes: 0
Views: 97
Reputation: 26343
Here is a data.table
solution
library(data.table)
setDT(df)[, .(time = seq(start, end)), by = val][]
# val time
# 1: a 2
# 2: a 3
# 3: a 4
# 4: b 2
# 5: b 3
# 6: b 4
# 7: b 5
# 8: c 1
# 9: c 2
#10: c 3
data
df <- structure(list(start = c(2L, 2L, 1L), end = c(4L, 5L, 3L), val = c("a",
"b", "c")), .Names = c("start", "end", "val"), class = "data.frame", row.names = c("1",
"2", "3"))
Upvotes: 1
Reputation: 145785
Here's one way:
dd$time = Map(f = seq, dd$start, dd$end)
tidyr::unnest(dd[c("val", "time")])
# val time
# 1 a 2
# 2 a 3
# 3 a 4
# 4 b 2
# 5 b 3
# 6 b 4
# 7 b 5
# 8 c 1
# 9 c 2
# 10 c 3
Using this sample data:
dd = read.table(text = "start end val
1 2 4 a
2 2 5 b
3 1 3 c", header = TRUE)
Upvotes: 2