Reducing list hierarchy with modify/flatten family of functions

Amendment to original post
The motivating idea is to remove the hierarchy of one particular element of a list. Or perhaps in other words, to elevate the contents of one element of a list to one level of hierarchy above it. In another example suppose we have this list:

mylist <- list(
    numbers = 1:4,
    list.of.letters = list(
        c("a", "b", "c"),
        c("x", "y", "z")
    ),
    list.of.dfs = list(
        foo = tibble(one = 1),
        bar = tibble(two = 2)
    )
)

> mylist
$numbers
[1] 1 2 3 4

$list.of.letters
$list.of.letters[[1]]
[1] "a" "b" "c"

$list.of.letters[[2]]
[1] "x" "y" "z"


$list.of.dfs
$list.of.dfs$foo
# A tibble: 1 x 1
    one
  <dbl>
1     1

$list.of.dfs$bar
# A tibble: 1 x 1
    two
  <dbl>
1     2

I would like to be able to pick out an element of a list (by name, or position, or perhaps even by a predicate) and elevate its contents to one hierarchy level above where it is currently at. So for instance, taking the contents of list.of.dfs and removing one level of hierarchy such that we get this desired output:

> c(mylist[1], mylist[2], flatten(mylist[3]))
$numbers
[1] 1 2 3 4

$list.of.letters
$list.of.letters[[1]]
[1] "a" "b" "c"

$list.of.letters[[2]]
[1] "x" "y" "z"


$foo
# A tibble: 1 x 1
    one
  <dbl>
1     1

$bar
# A tibble: 1 x 1
    two
  <dbl>
1     2

Original post
I'm having trouble figuring out how to correctly remove one level of hierarchy from a list, for one element of the list.

Example, say I have a 2-element list and the second element is a list of data frames:

library(tidyverse)

mylist <- list(
    one = 1,
    dfs = list(
        a = tibble(x = 2),
        b = tibble(y = 3)
    )
)

> mylist
$one
[1] 1

$dfs
$dfs$a
# A tibble: 1 x 1
      x
  <dbl>
1     2

$dfs$b
# A tibble: 1 x 1
      y
  <dbl>
1     3

I want to be able to remove the first level hierarchy of the second element of mylist, such that it turns the above list structure into a list of three with this structure:

c(mylist[1], flatten(mylist[2]))

$one
[1] 1

$a
# A tibble: 1 x 1
      x
  <dbl>
1     2

$b
# A tibble: 1 x 1
      y
  <dbl>
1     3

I tried using a combination of modify_in() or modify_at() along with flatten(), but the modify functions are going one level too deep (`[[` vs `[`) and is flattening the tibbles themselves, rather than the list in which they are contained.

> modify_at(mylist, "dfs", flatten)
$one
[1] 1

$dfs
$dfs$x
[1] 2

$dfs$y
[1] 3

Any ideas?

library(tidyverse)

mylist <- list(
  one = 1,
  dfs = list(
    a = tibble(x = 2),
    b = tibble(y = 3)
  )
)

(goal <- c(mylist[1], flatten(mylist[2])))

(possible_solution <-flatten(mylist))

identical( goal,
           possible_solution)

The motivating idea behind this is to remove the hierarchy of one particular element of the list, not the list in its entirety.

Could you reformulate your example and goal state to reflect this ?

Yep, edited original post.

library(tidyverse)

mylist <- mylist <- list(
  numbers = 1:4,
  list.of.letters = list(
    c("a", "b", "c"),
    c("x", "y", "z")
  ),
  list.of.dfs = list(
    foo = tibble(one = 1),
    bar = tibble(two = 2)
  )
)

(goal <- c(mylist[1], mylist[2], flatten(mylist[3])))

selective_flatten <- function(inlist,sublistname){
  list_not_sublist <- inlist[which(names(inlist)!=sublistname)]
  flatten_sub <- flatten(inlist[which(names(inlist)==sublistname)])
  c(list_not_sublist,flatten_sub)
}

(possible_solution <-selective_flatten(mylist,"list.of.dfs"))

identical( goal,
           possible_solution)

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.