Reputation: 8773
I have a data set which looks like this:
job_id start_hour duration
1 14 3
2 8 2
Job_id: the id of the job
start_hour: the hour at which the job starts
duration: the number of hours required for the job
I would like to turn it into a table where each line represents an hour for the job:
job_id hour
1 14
1 15
1 16
2 8
2 9
So I would have for each job, as much lines as the job requires hours to be done.
Is there an elegant way to do this in R?
Many thanks
Upvotes: 3
Views: 128
Reputation: 206167
This is also possible with simple base functions. First, an input data.frame
#sample data
dd<-data.frame(
job_id = 1:2,
start_hour = c(14, 8),
duration = c(3, 2)
)
Now we use Map
to walk through each row and expand it to the right size. Then we combine all the newly expanded rows into one data.frame with do.call(rbind,...)
#transformation
do.call(rbind,Map(function(id,start,dur) {
data.frame(
job_id=rep(id, dur),
hour=seq(from=start, by=1, length.out=dur))
}, dd$job_id, dd$start_hour, dd$duration))
which gives us
job_id hour
1 1 14
2 1 15
3 1 16
4 2 8
5 2 9
Upvotes: 2
Reputation: 14336
One way to do this is using the package plyr
(where d
is your original data frame)
ddply(d, .(job_id),
function(d) data.frame(job_id = d$job_id,
hour = d$start_hour:(d$start_hour + d$duration -1)))
Upvotes: 3