Here's a purrr-based approach:
library(purrr)
mylist <- list(7,
c(10, 11, 12, 211, 446, 469),
c(10, 11, 12, 13),
c(11, 12, 13, 215),
c(15, 16),
c(15, 17, 216, 225))
result <- mylist %>%
# check whether any numbers of an element are in any of the elements
map(~map_lgl(mylist, compose(any, `%in%`), .x)) %>%
unique() %>% # drop duplicated groups
map(~reduce(mylist[.x], union)) # subset lst by group and collapse subgroups
str(result)
#> List of 3
#> $ : num 7
#> $ : num [1:8] 10 11 12 211 446 469 13 215
#> $ : num [1:5] 15 16 17 216 225
The logic here is similar to Ronak's answer; I just find this easier to read. If you like, you could write the last line as map(~unique(flatten_dbl(mylist[.x]))) or split it into map(~mylist[.x]) %>% simplify_all() %>% map(unique).
For the indices of which element is aggregated to which group, just call which on the elements used for subsetting:
mylist %>%
map(~map_lgl(mylist, compose(any, `%in%`), .x)) %>%
unique() %>%
map(which) %>%
str()
#> List of 3
#> $ : int 1
#> $ : int [1:3] 2 3 4
#> $ : int [1:2] 5 6
An alternative logic for the whole thing is to make the list nested instead of the calls, which means the self-join is up front (with cross2), there's no subsetting later, and most of the functions are just set operations:
mylist %>%
map(cross2, mylist) %>%
modify_depth(2, reduce, ~if(length(intersect(.x, .y)) > 0) sort(union(.x, .y))) %>%
map(reduce, union) %>%
unique()
or using cross2's .filter parameter,
mylist %>%
map(cross2, mylist, ~length(intersect(.x, .y)) == 0) %>%
map(compose(sort, unique, unlist)) %>%
unique()
which could be condensed to
mylist %>%
map(function(element) sort(unique(unlist(cross2(element, mylist, ~length(intersect(.x, .y)) == 0))))) %>%
unique()
These approaches don't drop duplicate groups until the end, though, so they're likely less efficient.