Miao  Cai
Miao Cai

Reputation: 1014

How to expand a vector of integers into consecutive integers in each group in r

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

Answers (3)

Mark
Mark

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)
  • split x by group which results in a named list per group
  • using lapply on the names we can expand the integer range for each group
  • finally use do.call to rbind the results together.

Upvotes: 1

drJones
drJones

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

Sotos
Sotos

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

Related Questions