Saltar al contenido principal
LibreTexts Español

3.5: Listas y Atributos

  • Page ID
    55108
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    El siguiente tipo de datos importante en nuestro recorrido por R es la lista. Las listas son bastante similares a los vectores: son colecciones ordenadas de datos, indexables por número de índice, vector lógico y nombre (si se nombra la lista). Sin embargo, las listas pueden contener varios tipos diferentes de datos (incluidas otras listas). Supongamos que tenemos tres vectores diferentes que representan alguna información sobre la planta Arabidopsis thaliana.

    III.5_1_R_86_ATAL_DATA

    Entonces podemos usar la función list () para reunir estos vectores en una sola unidad con la clase “list”.

    III.5_2_R_87_athal_list

    Gráficamente, podríamos representar esta lista así:

    imagen

    Aquí, la sintaxis [1] indica que los elementos de la lista son vectores (como en cuando se imprimen vectores). Al igual que los vectores, las listas se pueden indexar por vector índice y vector lógico.

    III.5_4_R_88_athal_sublist

    Ambos de lo anterior asignan a la sublista de variables una lista parecida a:

    imagen

    Esto parece bastante sencillo: al subestablecer una lista con un vector de indexación se devuelve una lista más pequeña con los elementos solicitados. Pero esta regla puede ser engañosa si olvidamos que un vector es el elemento más básico de los datos. Debido a que 2 es el vector de longitud uno c (2), athal [2] devuelve no el segundo elemento de la lista athal, sino más bien una lista de longitud uno con un solo elemento (el vector de ecotipos).

    III.5_6_R_89_Atal_Eco_List

    Una representación gráfica de esta lista:

    imagen

    Por lo tanto, necesitaremos una sintaxis diferente si queremos extraer un elemento individual de una lista. Esta sintaxis alternativa es athal [[2]].

    III.5_8_R_90_Atal_Eco_List

    Si quisiéramos extraer el segundo ecotipo directamente, necesitaríamos usar el second_ecotype relativamente torpe <- athal [[2]] [2], que accede al segundo elemento del vector (accedido por [2]) dentro del del segundo elemento de la lista (accedido por [[2]]).

    III.5_9_R_91_Athal_list_print

    Cuando imprimimos una lista, esta estructura y la sintaxis de doble corchete se refleja en la salida.

    III.5_10_R_92_athal_list_print_out

    Listas con nombre, listas dentro de listas

    Al igual que los vectores, las listas se pueden nombrar, asociadas con un vector de caracteres de igual longitud, usando la función names (). Podemos usar un vector índice de nombres para extraer una sublista, y podemos usar la sintaxis [[]] para extraer elementos individuales por nombre.

    III.5_11_R_93_Atal_list_nombre_extracto1

    Incluso podemos extraer elementos de una lista si el nombre del elemento que queremos se almacena en otra variable, usando la sintaxis [[]].

    III.5_12_R_94_Atal_list_nombre_extracto2

    Por muy divertida que sea esta sintaxis de doble corchete, debido a que extraer elementos de una lista por su nombre es una operación común, hay un atajo usando sintaxis $.

    III.5_13_R_95_Atal_list_nombre_extracto3

    De hecho, si el nombre no contiene ningún carácter especial (espacios, etc.), entonces se pueden dejar las comillas.

    III.5_14_R_96_Atal_list_nombre_extracto4

    Este atajo es ampliamente utilizado y conveniente, pero, debido a que las comillas están implícitas, no podemos usar la sintaxis $ para extraer un elemento por nombre si ese nombre está almacenado en una variable intermediaria. Por ejemplo, si extract_name <- “ecotipos”, entonces athal$extract_name se expandirá a athal [["extract_name"]], y no obtendremos el vector de ecotipos. Este error común refleja un malentendido del azúcar sintáctico empleado por R. Del mismo modo, la sintaxis $ no funcionará para nombres como “# Cromosomas” porque ese nombre contiene un espacio y un carácter especial (por esta razón, los nombres de los elementos de la lista suelen simplificarse).

    Frecuentemente, la sintaxis $ se combina con la sintaxis vectorial si el elemento de la lista al que se hace referencia es un vector. Por ejemplo, podemos extraer directamente el tercer ecotipo, o establecer el tercer ecotipo.

    III.5_15_R_97_athal_list_nombre_dollar_vector

    Continuando con este ejemplo, supongamos que tenemos otra lista que describe información sobre cada cromosoma. Podemos comenzar con una lista vacía, y asignarle elementos por nombre.

    III.5_16_R_98_Chrs_list

    Esta lista de dos elementos se relaciona con A. thaliana, por lo que tiene sentido incluirla de alguna manera en la lista athal. Afortunadamente, las listas pueden contener otras listas, por lo que asignaremos esta lista de chrs como elemento de la lista athal.

    III.5_17_R_99_Atal_estructura_completa

    Las listas son un excelente contenedor para colecciones generales de datos heterogéneos en un solo “objeto” organizado. (Estos difieren de los objetos Python en que no tienen métodos almacenados en ellos también, pero veremos cómo funciona R con métodos en capítulos posteriores). Si corriéramos print (athal) en este punto, toda esta información sería impresa, pero desafortunadamente de una manera bastante antipática:

    III.5_18_R_100_athal_estructura_completa_print

    Este resultado sí ilustra algo de interés, sin embargo. Podemos encadenar la sintaxis $ para acceder a elementos de listas y listas contenidas por nombre. Por ejemplo, length <- athal$chrinfo$length extrae el vector de longitudes contenido en la lista interna de ChrInfo, e incluso podemos modificar elementos de estos vectores con sintaxis como athal$chrinfo$geneCounts [1] <- 7079 (quizás un nuevo gen fue descubierto recientemente en el primer cromosoma). Ampliando la sintaxis un poco para usar corchetes dobles en lugar de notación $, estas son equivalentes a longitudes <- athal [["ChrInfo"]] [["Longitudes"]] y athal [["ChrInfo"]] [["GeneCounts"]] [1] <- 7079.

    Atributos, Eliminación de Elementos, Estructura de Lista

    Las listas son una excelente manera de organizar datos heterogéneos, especialmente cuando los datos se almacenan en una asociación Nombre Valor, [1] facilitando el acceso a los datos por nombre de carácter. Pero, ¿y si queremos buscar alguna información asociada a un dato pero no representada en los propios datos? Esto sería un tipo de “metadatos”, y R nos permite asociar metadatos a cualquier dato usando lo que se llama atributos. Supongamos que tenemos un vector simple de datos normalmente distribuidos:

    III.5_19_R_101_ATTR_NORM_VEC

    Posteriormente, podríamos querer saber qué tipo de datos son estos: ¿se distribuyen normalmente, o algo más? Podemos resolver este problema asignando el término “normal” como atributo de los datos. El atributo también necesita un nombre, al que llamaremos “disttype”. Los atributos se asignan de manera similar a los nombres.

    III.5_20_R_102_ATTR_NORM_VEC_ATTR

    Cuando se imprime, la salida muestra los atributos que también se han asignado.

    III.5_21_R_103_ATTR_NORM_VEC_ATTR_OUT

    Podemos extraer por separado un atributo dado de un elemento de datos, usando sintaxis como sample_dist <- attr (sample, “disttype”). Los atributos se utilizan ampliamente en R, aunque rara vez se modifican en el uso diario del idioma. [2]

    Para ampliar nuestro ejemplo de A. thaliana, asignemos un atributo de “reino” al vector especie.

    III.5_22_R_104_ATHAL_ATHAL_ATRO

    En este punto, hemos construido una estructura bastante sofisticada: una lista que contiene vectores (uno de los cuales tiene un atributo) y otra lista, en sí misma que contiene vectores, con los diversos elementos de la lista siendo nombrados. Si fuéramos a ejecutar print (athal), veríamos una salida bastante desordenada. Afortunadamente, R incluye una alternativa a print () llamada str (), que imprime muy bien la estructura de una lista (u otro objeto de datos). Aquí está el resultado de llamar a str (athal) en este punto.

    III.5_23_R_105_Athal_str

    Eliminar un elemento o atributo de una lista es tan simple como asignarle el valor especial NULL.

    III.5_24_R_106_Athal_Delete

    La estructura impresa revela que esta información ha sido eliminada.

    III.5_25_R_107_Atal_Delete_out

    ¿Cuál es el punto de toda esta lista detallada y asignación de atributos? Resulta ser bastante importante, porque muchas funciones R devuelven exactamente este tipo de listas complejas cargadas de atributos. Considere la función t.test (), que compara las medias de dos vectores para la igualdad estadística:

    III.5_26_R_108_TTEST_PRINT

    Cuando se imprime, el resultado es un resultado muy bien formateado y legible por humanos.

    III.5_27_R_109_TTEST_PRINT_OUT

    Si ejecutamos str (tresult), sin embargo, encontramos la verdadera naturaleza de tresult: ¡es una lista!

    III.5_28_R_110_TTEST_STR

    Dado el conocimiento de esta estructura, podemos extraer fácilmente elementos específicos, como el valor p con pval <- tresult$p.value o pval <- tresult [["p.value"]].

    Una nota final sobre listas: vectores (y otros tipos) se pueden convertir en una lista con la función.list (). Esto será útil más adelante, porque las listas son uno de los tipos de datos más generales en R, y podemos utilizarlas para representaciones de datos intermediarios.

    III.5_29_R_110_2_com_lista_como

    Ejercicios

    1. El siguiente código genera primero una muestra aleatoria llamada a, y luego una muestra llamada respuesta, donde cada elemento de respuesta es un elemento de un veces 1.5 más algo de ruido aleatorio:III.5_30_R_110_3_LINEAR_DEPEND A continuación, podemos crear fácilmente un modelo lineal que predice valores de respuesta de a:III.5_31_R_110_4_LM_Modelo Cuando se imprime, la salida describe muy bien los parámetros del modelo. III.5_32_R_110_5_LM_Model_outTambién podemos probar fácilmente la significancia de los parámetros con la función anova () (para ejecutar una prueba de análisis de varianza en el modelo). III.5_33_R_110_6_ANOVALa salida nuevamente muestra texto muy bien formateado:III.5_34_R_110_7_Anova_out Del modelo, extraer el coeficiente de a en una variable llamada a_coeff (que contendría solo el número 1.533367 para esta muestra aleatoria) .Siguiente, de vartest extraer el valor p asociado con el coeficiente a en un vector llamado a_pval (para esta muestra aleatoria, el valor p es 2.2e-16).
    2. Escribe una función llamada simple_lm_pval () que automatiza el proceso anterior; debería tomar dos parámetros (dos vectores numéricos potencialmente dependientes linealmente) y devolver el valor p asociado al primer coeficiente (nonintercept).
    3. Cree una lista que contenga tres muestras aleatorias de diferentes distribuciones (por ejemplo, de rnorm (), runif () y rexp ()), y agregue un atributo para “disttype” a cada una. Use print () y str () en la lista para examinar los atributos que agregó.
    4. Algunos nombres se pueden usar con notación $ sin comillas; si l <- list (values = c (20, 30)), entonces print (l$values) imprimirá el vector interno. Por otro lado, si l <- list (“val-entries” = c (20, 30)), entonces se requieren cotizaciones como en forma impresa (l$"val-entries”). Por experimentación, determinar al menos cinco caracteres diferentes que requieren el uso de comillas al usar notación $.
    5. Experimenta con las funciones is.list () y as.list (), probando cada una de ellas tanto en vectores como en listas.

    1. Las listas R se utilizan a menudo como diccionarios en Python y tablas hash en otros idiomas, debido a esta operación de búsqueda de nombre valor fácil y efectiva. Cabe señalar que (al menos a partir de R 3.3), las búsquedas de nombres en las listas no son tan eficientes como las búsquedas de nombres en diccionarios Python u otras tablas hash verdaderas. Para una operación eficiente y más idiomática de tabla/diccionario hash, también existe el hash del paquete disponible para instalar con install.packages (“hash”).
    2. Por ejemplo, los nombres de un vector se almacenan como un atributo llamado “nombres” —los nombres de líneas (puntuaciones) <- c (“Estudiante A”, “Estudiante B”, “Estudiante C”) y attr (puntuaciones, “nombres”) <- c (“Estudiante A”, “Estudiante B”, “Estudiante C”) son (casi) equivalentes. Aún así, se recomienda usar funciones especializadas como names () en lugar de establecerlas con attr () porque la función names () incluye comprobaciones adicionales sobre la cordura del vector names.

    This page titled 3.5: Listas y Atributos is shared under a CC BY-NC-SA license and was authored, remixed, and/or curated by Shawn T. O’Neil (OSU Press) .