Reputation: 1014
I want to expand a vector of integers into consecutive integers in each group in r. Can anyone have some hints on this problem?
Below is my original dataset:
x = c(1, 2, 3, 4, 5, 1, 3, 5, 6, 1, 2, 3, 6, 8)
group = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3)
data = data.frame(x, group)
and my desired dataset is as below:
desired_data = data.frame(
x = c(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8),
group = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3))
Thanks for your help!
Upvotes: 1
Views: 170
Reputation: 4537
Here's a base R solution.
x = c(1, 2, 3, 4, 5, 1, 3, 5, 6, 1, 2, 3, 6, 8)
group = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3)
sl = split(x,group)
expanded = lapply(names(sl),function(x){
r = range(sl[[x]])
return(data.frame(x = seq(r[1],r[2],1),group = x))
})
do.call(rbind,expanded)
lapply
on the names we can expand the integer range for each groupdo.call
to rbind the results together.Upvotes: 1
Reputation: 1233
I'm sure someone will have a cleaner solution soon. In the meantime:
minVals=aggregate(data$x, by = list(data$group), min)[,2]
maxVals=aggregate(data$x, by = list(data$group), max)[,2]
ls=apply(cbind(minVals,maxVals),1,function(x) x[1]:x[2])
desired_data = data.frame(
x = unlist(ls),
group = rep(unique(data$group),lapply(ls,length)))
x group
1 1 1
2 2 1
3 3 1
4 4 1
5 5 1
6 1 2
7 2 2
8 3 2
9 4 2
10 5 2
11 6 2
12 1 3
13 2 3
14 3 3
15 4 3
16 5 3
17 6 3
18 7 3
19 8 3
Upvotes: 1
Reputation: 51592
This can be easily done via expand
from tidyr
,
library(tidyverse)
df %>%
group_by(group) %>%
expand(x = full_seq(x, 1))
Which gives,
# A tibble: 19 x 2 # Groups: group [3] group x <dbl> <dbl> 1 1 1 2 1 2 3 1 3 4 1 4 5 1 5 6 2 1 7 2 2 8 2 3 9 2 4 10 2 5 11 2 6 12 3 1 13 3 2 14 3 3 15 3 4 16 3 5 17 3 6 18 3 7 19 3 8
Upvotes: 4