Given a data.frame where start and end represents ranges.
id start end
1 3 51
2 20 28
I'm trying to split the rows into multiple rows if the range contains another number or sequence of numbers and grouping them, for example by 25
id start end splitGroup
1 3 25 0
1 25 51 25
2 20 25 0
2 25 28 25
Functioning similarly to splitting by a regular sequence here using the plyr package
df <- data.frame(
id = c(1:2),
start = c(3,20),
end = c(51,28)
)
splitBy <- 20
rowSplit <- function(df, splitBy){
newDf <- ddply(df, .(id), function(x){
data.frame(
id = x$id,
start = x$start,
end = x$end,
splitGroup = seq(
floor(x$start/splitBy)*splitBy,
floor(x$end/splitBy)*splitBy,
by=splitBy
)
)
})
newDf <- within(newDf, {
start <- ifelse(
floor(start/splitBy)*splitBy == splitGroup,
start,
splitGroup
)
end <- ifelse(
end < (splitGroup + splitBy),
end,
(splitGroup + splitBy)
)
})
return(newDf)
}
rowSplit(df, splitBy)
id start end splitGroup
1 3 20 0
1 20 40 20
1 40 51 40
2 20 28 20
How can this be done using any singel number or irregular set of numbers
Here's a start at using a mod function:
smod <- df$start%/%25 # 0 0
emod<-df$end%/%25 # 2 1
newstart<-numeric(0)
matchit<-25*(1:100) # or at least extend to maximum value in your dataframe
for (j in 1:2) { newstart<-c(newstart,df$start[j])
if(emod[j]>0) newstart<-c(newstart, min(matchit[matchit>df$start[j]])) }
Rgames> newstart
[1] 3 25 20 25
Calculate newend in a similar manner and you should be set.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With