I trying to create what I'm calling a recursively nested tibble, a tibble with x rows that is nested such that each x row nests the following n rows of y. Here is an example of what I'm trying to achieve.
Given the tibble df:
df <- tibble(x = 5:1, y = 5:1)
I'm trying to produce a nested tibble that looks like this: (where data is the nested column)
The one approach I came up with was to use uncount to replicate the original tibble and then add an id column that represents each version of the tibble. Next, I grouped on the id column and then nested the tibble. From here create an index column for each group and filter out what I don't want. This may get me there, but its there must be a more elegant way to achieve this. I'd appreciate any thoughts or insights anyone has.
df <- tibble(x = 5:1, y = 5:1)
z <- uncount(df, 5, .id = "id")
z <- z %>%
arrange(id) %>%
select(id, x, y) %>%
group_by(id) %>%
mutate(n = row_number()-1)
Using purrr::map
(or lapply
) and tidyr::unnest
you could do:
library(dplyr, warn = FALSE)
library(purrr)
library(tidyr)
df <- tibble(x = 5:1, y = 5:1)
n <- 3
df |>
mutate(
data = map(y, \(x) {
y <- rev(seq_len(x - 1))
tibble(y = y[seq_len(min(length(y), n))])
}),
.keep = "unused"
) |>
unnest(data, keep_empty = TRUE)
#> # A tibble: 10 × 2
#> x y
#> <int> <int>
#> 1 5 4
#> 2 5 3
#> 3 5 2
#> 4 4 3
#> 5 4 2
#> 6 4 1
#> 7 3 2
#> 8 3 1
#> 9 2 1
#> 10 1 NA