Below is a reprex of the problem including the solution I've come up with. However, I feel like there is a more efficient way of doing this.
Specifically check out the have
and want
tibbles to see what I am going for. The former has columns from
and to
that should translate to the year
column in the latter.
library(tidyverse)
have <- tribble(
~V1, ~V2, ~from, ~to,
"a", "b", 2010, 2013,
"c", "d", 2010, 2010,
"c", "e", 2011, 2013
)
have
#> # A tibble: 3 × 4
#> V1 V2 from to
#> <chr> <chr> <dbl> <dbl>
#> 1 a b 2010 2013
#> 2 c d 2010 2010
#> 3 c e 2011 2013
want <- list()
for(i in 1:nrow(have)){
slice_i <- have %>% slice(i)
seqtab_i <- tibble(year = seq(slice_i$from, slice_i$to))
want[[i]] <- slice_i %>%
select(-from, -to) %>%
bind_cols(seqtab_i)
}
want <- bind_rows(want)
want
#> # A tibble: 8 × 3
#> V1 V2 year
#> <chr> <chr> <int>
#> 1 a b 2010
#> 2 a b 2011
#> 3 a b 2012
#> 4 a b 2013
#> 5 c d 2010
#> 6 c e 2011
#> 7 c e 2012
#> 8 c e 2013
Created on 2022-12-06 with reprex v2.0.2
CodePudding user response:
library(tidyverse)
df %>%
group_by(V1, V2) %>%
group_modify(~ add_row(from = first(.$to), .x)) %>%
select(-to, year = from) %>%
complete(year = first(year):max(year)) %>%
distinct_all()
# A tibble: 8 × 3
# Groups: V1, V2 [3]
V1 V2 year
<chr> <chr> <dbl>
1 a b 2010
2 a b 2011
3 a b 2012
4 a b 2013
5 c d 2010
6 c e 2011
7 c e 2012
8 c e 2013
CodePudding user response:
You can use map to sequence the years between each row. This will provide you with a list of the years for each applicable row, you can then use unnest() to flatten this.
see code below:
have <- tribble(
~V1, ~V2, ~from, ~to,
"a", "b", 2010, 2013,
"c", "d", 2010, 2010,
"c", "e", 2011, 2013
)
df <- have %>%
mutate(years = map2(from, to, seq)) %>%
unnest(years) %>%
select(V1, V2, years)
CodePudding user response:
another solution
library(tidyverse)
have |>
rowwise() |>
mutate(year = list(seq(from, to))) |>
unnest(year) |>
select(-c(from, to))
#> # A tibble: 8 × 3
#> V1 V2 year
#> <chr> <chr> <int>
#> 1 a b 2010
#> 2 a b 2011
#> 3 a b 2012
#> 4 a b 2013
#> 5 c d 2010
#> 6 c e 2011
#> 7 c e 2012
#> 8 c e 2013