es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Función para combinar múltiples listas de listas en una sola lista de listas.

Supongamos que tenemos la lista l, que es una lista de listas.

a <- list(c(1,2,3))
b <- list(c(4,5,6), c(7,8,9))
c <- list(c(10,11,12), c(13,14,15), c(16,17,18))

l <- list(a, b, c)

Entonces, l es una lista de listas, donde cada una de esas listas contiene al menos una lista.

Pregunta

¿Cómo puedo crear una función que extraiga todas las listas de nivel más bajo en una única lista de listas?


<h1>Objetivo</h1> <p>list(c(1,2,3), c(4,5,6), c(7,8,9), c(10,11,12), c(13,14,15), c(16,17,18)) ```</p> Notas: <ul> <li>El ejemplo es un ejemplo mínimo reproducible para el cual sería posible codificar una solución, pero es importante que la solución sea general, ya que el problema real tiene decenas de miles de listas, cada una de las cuales contiene un número desconocido de listas, por lo que una solución codificada no se ajustaría a escala de manera eficiente.</p></li> <li><p>Espero encontrar una solución en R base, si es posible.</p></li> </ul> <h3>Algunas cosas que he intentado hasta ahora</h3> <p>Algunos intentos fallidos, principalmente usando <code>sapply()</code> y <code>unlist()</code>: ```r sapply(l, function(x) { unlist(x) })

[[1]]

[1] 1 2 3

[[2]]

[1] 4 5 6 7 8 9

[[3]]

[1] 10 11 12 13 14 15 16 17 18

unlist(a)

[1] 1 2 3

unlist() parece combinar los elementos de múltiples listas en una sola lista (no deseado aquí)..

unlist(b)

[1] 4 5 6 7 8 9


Pensé que el argumento <a href="https://stackoverflow.com/a/43281952/5783745"><code>recursive = FALSE</code></a> parecía prometedor, pero desafortunadamente tampoco pude lograr lo que quería:

```r
unlist(b, recursive = FALSE)
</code></pre>

<h1>[1] 4 5 6 7 8 9</h1>

```

Tags:  ,

Answer

  1. Avatar for davy.ai

    La función unlist() es un buen comienzo, pero como mencionaste, combina todos los elementos en una única lista, lo cual no es lo que queremos. Necesitamos una función que pueda recorrer de forma recursiva cada una de las listas y solo desglose las que están en el nivel más bajo. Aquí tienes una función que logra eso:

    flatten_lists <- function(lst) {
      if (!is.list(lst)) {
        # caso base: si el elemento no es una lista, se devuelve tal cual
        return(lst)
      } else {
        # caso recursivo: aplicar flatten_lists a cada elemento de la lista
        return(do.call(c, lapply(lst, flatten_lists)))
      }
    }
    

    Desglosemos esto:

    • La función toma un único argumento lst, que es la lista que queremos desglosar.
    • Si lst no es una lista, simplemente lo devolvemos tal cual. Este es el caso base que detiene la recursión.
    • Si lst es una lista, aplicamos flatten_lists() a cada elemento de la lista usando lapply().
    • Luego, usamos do.call() para concatenar estas listas individuales en una sola lista.
    • Este proceso continúa de forma recursiva hasta que todas las listas anidadas hayan sido desglosadas.

    Ahora podemos aplicar esta función a tu lista de ejemplo l y obtener el resultado deseado:

    flatten_lists(l)
    #> [[1]]
    #> [1] 1 2 3
    #> 
    #> [[2]]
    #> [1] 4 5 6
    #> 
    #> [[3]]
    #> [1] 7 8 9
    #> 
    #> [[4]]
    #> [1] 10 11 12
    #> 
    #> [[5]]
    #> [1] 13 14 15
    #> 
    #> [[6]]
    #> [1] 16 17 18
    

    Ten en cuenta que el resultado es una lista de listas, que es lo que queremos. Esta función también debería funcionar con listas más grandes con un número desconocido de listas anidadas, ya que utiliza la recursión para manejar cualquier nivel de anidamiento.

Comments are closed.