Buscar..


Introducción rápida a las listas

En general, la mayoría de los objetos con los que interactuarías como usuario tenderían a ser un vector; Ej. vector numérico, vector lógico. Estos objetos solo pueden tomar en un solo tipo de variable (un vector numérico solo puede tener números en su interior).

Una lista podría almacenar cualquier variable de tipo en ella, convirtiéndola en el objeto genérico que puede almacenar cualquier tipo de variables que necesitemos.

Ejemplo de inicialización de una lista

exampleList1 <- list('a', 'b')
exampleList2 <- list(1, 2)
exampleList3 <- list('a', 1, 2)

Para entender los datos que se definieron en la lista, podemos usar la función str.

str(exampleList1)
str(exampleList2)
str(exampleList3)

El subconjunto de listas distingue entre extraer una porción de la lista, es decir, obtener una lista que contenga un subconjunto de los elementos en la lista original y extraer un solo elemento. El uso del [ operador comúnmente utilizado para vectores produce una nueva lista.

# Returns List
exampleList3[1]
exampleList3[1:2]

Para obtener un solo elemento use [[ lugar.

# Returns Character
exampleList3[[1]]

Las entradas de la lista pueden ser nombradas:

exampleList4 <- list(
    num = 1:3,
    numeric = 0.5,
    char = c('a', 'b')
)

Se puede acceder a las entradas en las listas con nombre por su nombre en lugar de su índice.

exampleList4[['char']]

Alternativamente, el operador $ se puede usar para acceder a los elementos nombrados.

exampleList4$num

Esto tiene la ventaja de que es más rápido de escribir y puede ser más fácil de leer, pero es importante estar al tanto de una posible trampa. El operador $ usa una coincidencia parcial para identificar los elementos de la lista y puede producir resultados inesperados.

exampleList5 <- exampleList4[2:3]

exampleList4$num
# c(1, 2, 3)

exampleList5$num
# 0.5

exampleList5[['num']]
# NULL

Las listas pueden ser particularmente útiles porque pueden almacenar objetos de diferentes longitudes y de varias clases.

## Numeric vector
exampleVector1 <- c(12, 13, 14)
## Character vector
exampleVector2 <- c("a", "b", "c", "d", "e", "f")
## Matrix
exampleMatrix1 <- matrix(rnorm(4), ncol = 2, nrow = 2)
## List
exampleList3 <- list('a', 1, 2)

exampleList6 <- list(
    num = exampleVector1, 
    char = exampleVector2,
    mat = exampleMatrix1, 
    list = exampleList3
)
exampleList6
#$num
#[1] 12 13 14
#
#$char
#[1] "a" "b" "c" "d" "e" "f"
#
#$mat
#          [,1]        [,2]
#[1,] 0.5013050 -1.88801542
#[2,] 0.4295266  0.09751379
#
#$list
#$list[[1]]
#[1] "a"
#
#$list[[2]]
#[1] 1
#
#$list[[3]]
#[1] 2

Introducción a las listas

Las listas permiten a los usuarios almacenar múltiples elementos (como vectores y matrices) en un solo objeto. Puede utilizar la función de list para crear una lista:

l1 <- list(c(1, 2, 3), c("a", "b", "c"))
l1
## [[1]]
## [1] 1 2 3
## 
## [[2]]
## [1] "a" "b" "c"

Observe que los vectores que conforman la lista anterior son clases diferentes. Las listas permiten a los usuarios agrupar elementos de diferentes clases. Cada elemento en una lista también puede tener un nombre. Los nombres de lista son accedidos por la función de names , y se asignan de la misma manera que los nombres de filas y columnas se asignan en una matriz.

names(l1)
## NULL
names(l1) <- c("vector1", "vector2")
l1
## $vector1
## [1] 1 2 3
## 
## $vector2
## [1] "a" "b" "c"

A menudo es más fácil y más seguro declarar los nombres de lista al crear el objeto de lista.

l2 <- list(vec = c(1, 3, 5, 7, 9),
       mat = matrix(data = c(1, 2, 3), nrow = 3))
l2
## $vec
## [1] 1 3 5 7 9
## 
## $mat
##      [,1]
## [1,]    1
## [2,]    2
## [3,]    3
names(l2)
## [1] "vec" "mat"

Encima de la lista hay dos elementos, llamados "vec" y "mat", un vector y una matriz, resepcivamente.

Razones para usar listas

Para el usuario R promedio, la estructura de la lista puede parecer una de las estructuras de datos más complicadas de manipular. No hay garantías de que todos los elementos que contiene sean del mismo tipo; No hay una estructura garantizada de cuán complicada / no complicada sería la lista (un elemento en una lista podría ser una lista)

Sin embargo, una de las razones principales cuando se usan listas para usarla para pasar parámetros entre funciones.

# Function example which returns a single element numeric vector
exampleFunction1 <- function(num1, num2){
    result <- num1 + num2
    return(result)
}

# Using example function 1
exampleFunction1(1, 2)

# Function example which returns a simple numeric vector
exampleFunction2 <- function(num1, num2, multiplier){
    tempResult1 <- num1 + num2
    tempResult2 <- tempResult1 * multiplier
    result <- c(tempResult1, tempResult2)
    return(result) 
}

# Using example function 2
exampleFunction2(1, 2, 4)

En el ejemplo anterior, los resultados devueltos son simplemente vectores numéricos simples. No hay problemas para pasar sobre vectores tan simples.

Es importante tener en cuenta que en este punto, en general, las funciones R solo devuelven 1 resultado a la vez (puede usar las condiciones para obtener resultados diferentes). Sin embargo, si pretende crear una función que toma un conjunto de parámetros y devuelve varios tipos de resultados, como un vector numérico (valor de configuración) y un marco de datos (del cálculo), deberá volcar todos estos resultados en una lista antes de devolverlo.

# We will be using mtcars dataset here
# Function which returns a result that is supposed to contain multiple type of results
# This can be solved by putting the results into a list
exampleFunction3 <- function(dataframe, removeColumn, sumColumn){
    resultDataFrame <- dataframe[, -removeColumn]
    resultSum <- sum(dataframe[, sumColumn])
    resultList <- list(resultDataFrame, resultSum)
    return(resultList)
}

# Using example function 3
exampleResult <- exampleFunction3(mtcars, 2, 4)
exampleResult[[1]]
exampleResult[[2]]

Convierta una lista en un vector mientras mantiene los elementos de la lista vacía.

Cuando se desea convertir una lista a un vector o un objeto data.frame, normalmente se eliminan los elementos vacíos.

Esto puede ser problemático, ya que se crea una lista de una longitud deseada con algunos valores vacíos (por ejemplo, se crea una lista con n elementos para agregarse a una matriz mxn, data.frame o data.table). Sin embargo, es posible convertir sin pérdidas una lista en un vector, conservando elementos vacíos:

res <- list(character(0), c("Luzhuang", "Laisu", "Peihui"), character(0), 
    c("Anjiangping", "Xinzhai", "Yongfeng"), character(0), character(0), 
    c("Puji", "Gaotun", "Banjingcun"), character(0), character(0), 
    character(0))
res
[[1]]
character(0)

[[2]]
[1] "Luzhuang" "Laisu"    "Peihui"  

[[3]]
character(0)

[[4]]
[1] "Anjiangping" "Xinzhai"     "Yongfeng"   

[[5]]
character(0)

[[6]]
character(0)

[[7]]
[1] "Puji"       "Gaotun"     "Banjingcun"

[[8]]
character(0)

[[9]]
character(0)

[[10]]
character(0)
res <- sapply(res, function(s) if (length(s) == 0) NA_character_ else paste(s, collapse = " "))
res
 [1] NA                             "Luzhuang Laisu Peihui"        NA                             "Anjiangping Xinzhai Yongfeng" NA      

 [6] NA                             "Puji Gaotun Banjingcun"       NA                             NA                             NA

Serialización: uso de listas para pasar informaciones.

Existen casos en los que es necesario juntar datos de diferentes tipos. En Azure ML, por ejemplo, es necesario pasar información de un módulo de script R a otro exclusivamente a través de marcos de datos. Supongamos que tenemos un marco de datos y un número:

> df
       name height        team fun_index title age         desc Y
1    Andrea    195       Lazio        97     6  33   eccellente 1
2      Paja    165  Fiorentina        87     6  31       deciso 1
3      Roro    190       Lazio        65     6  28       strano 0
4    Gioele     70       Lazio       100     0   2    simpatico 1
5     Cacio    170    Juventus        81     3  33         duro 0
6     Edola    171       Lazio        72     5  32     svampito 1
7    Salami    175       Inter        75     3  30  doppiopasso 1
8    Braugo    180       Inter        79     5  32          gjn 0
9     Benna    158    Juventus        80     6  28     esaurito 0
10   Riggio    182       Lazio        92     5  31     certezza 1
11 Giordano    185        Roma        79     5  29        buono 1

> number <- "42"

Podemos acceder a esta información:

> paste(df$name[4],"is a",df3$team[4], "supporter." )
[1] "Gioele is a  Lazio supporter."
> paste("The answer to THE question is", number )
[1] "The answer to THE question is 42"

Para colocar diferentes tipos de datos en un marco de datos, debemos utilizar la lista de objetos y la serialización. En particular, tenemos que poner los datos en una lista genérica y luego poner la lista en un marco de datos particular:

l <- list(df,number)
dataframe_container <- data.frame(out2 = as.integer(serialize(l, connection=NULL)))

Una vez que hayamos almacenado la información en el marco de datos, debemos deserializarla para poder utilizarla:

#----- unserialize ----------------------------------------+
unser_obj <- unserialize(as.raw(dataframe_container$out2))
#----- taking back the elements----------------------------+
df_mod        <- unser_obj[1][[1]]  
number_mod    <- unser_obj[2][[1]]

Entonces, podemos verificar que los datos son transferidos correctamente:

> paste(df_mod$name[4],"is a",df_mod$team[4], "supporter." )
[1] "Gioele is a  Lazio supporter."
> paste("The answer to THE question is", number_mod )
[1] "The answer to THE question is 42"


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow