#Listas de objetos La lista es una estructura de datos increíblemente útil. Puede utilizarse para agrupar cualquier combinación de estructuras y objetos de R. Una sola lista puede contener una matriz numérica, una matriz lógica, una cadena de caracteres y un objeto factor. Incluso puede tener una lista como componente de otra lista. En esta sección verá cómo crear, modificar y acceder a componentes de estas estructuras flexibles.

#5.1.1 Definición y acceso a componentes

Crear una lista es muy parecido a crear un vector. Se suministran los elementos que a la función lista, separados por comas. R> foo <- list(matrix(data=1:4,nrow=2,ncol=2),c(T,F,T,T), “hola”) R> foo [[1]] [,1] [,2] [1,] 1 3 [2,] 2 4 [[2]] [1] TRUE FALSE TRUE [[3]] [1] “hola” En la lista foo, has almacenado una matriz numérica de 2 × 2, un vector lógico y una cadena de caracteres. Éstos se imprimen en el orden en que se han introducido en la lista. Al igual que con los vectores, puede utilizar la función longitud para comprobar el número de componentes de una lista. componentes de una lista. R> longitud(x=foo) [1] 3 Puede recuperar componentes de una lista utilizando índices, que se introducen entre corchetes dobles. introducidos entre corchetes dobles. R> foo[[1]] [,1] [,2] [1,] 1 3 [2,] 2 4 R> foo[[3]] [1] “hola”

Esta acción se conoce como referencia a un miembro. Cuando hayas recuperado un componente componente de esta manera, puede tratarlo como un objeto independiente en el espacio de trabajo. espacio de trabajo; no hay que hacer nada especial.

R> foo[[1]] + 5.5 [,1] [,2] [1,] 6.5 8.5 [2,] 7.5 9.5 R> foo[[1]][1,2] [1] 3 R> foo[[1]][2,] [1] 2 4 R> cat(foo[[3]], “¡tú!”) ¡hola tú!

90 Capítulo 5 Para sobrescribir un miembro de foo, se utiliza el operador de asignación.

R> foo[[3]] [1] “hola” R> foo[[3]] <- paste(foo[[3]], “¡tú!”) R> foo [[1]] [,1] [,2] [1,] 1 3 [2,] 2 4 [[2]] [1] TRUE FALSE TRUE [[3]] [1] “¡hola!”

Supongamos ahora que quieres acceder a los componentes segundo y tercero de foo y almacenarlos como un único objeto. Tu primer instinto podría ser intentar algo así:

R> foo[[c(2,3)]] [1] TRUE

Pero R no ha hecho lo que querías. En su lugar, ha devuelto el tercer elemento del segundo componente. Esto se debe a que el uso de corchetes dobles en una lista siempre se interpreta con respecto a un solo miembro. Afortunadamente, la referenciación de miembros con los corchetes dobles no es la única forma de acceder a los componentes de una lista. forma de acceder a los componentes de una lista. También se puede utilizar la notación simples. Este método se denomina troceado de listas y permite seleccionar varios elementos de la lista a la vez.

R> bar <- foo[c(2,3)] R> bar [[1]] [1] TRUE FALSE TRUE [[2]] [1] “¡hola!”

Tenga en cuenta que la barra de resultados es en sí misma una lista con los dos componentes almacenados en en el orden en que fueron solicitados.

#5.1.2 Asignación de nombres

Puede asignar nombres a los componentes de la lista para que los elementos sean más reconocibles y más reconocibles y fáciles de utilizar. Al igual que la información almacenada sobre los niveles de los factores (como en la sección 4.3.1), un nombre es un atributo R. Listas y marcos de datos 91 Empecemos añadiendo nombres a la lista foo de antes.

R> names(foo) <- c(“mymatrix”, “mylogicals”, “mystring”) R> foo $mimatriz [,1] [,2] [1,] 1 3 [2,] 2 4 $milógicas [1] TRUE FALSE TRUE $cadena [1] “¡hola a ti!” Esto ha cambiado cómo se imprime el objeto en la consola. Donde antes imprimía [[1]], [[2]], y [[3]] antes de cada componente, ahora imprime los nombres especificados: $mymatrix, $mylogicals, y \(mystring. Ahora puede realizar referencias a miembros utilizando estos nombres y el operador dólar en lugar de los corchetes dobles. R> foo\)mimatriz

[,1] [,2] [1,] 1 3 [2,] 2 4

Esto es lo mismo que llamar a foo[[1]]. De hecho, incluso cuando un objeto es nombrado, todavía se puede utilizar el índice numérico para obtener un miembro. R> foo[[1]] [,1] [,2] [1,] 1 3 [2,] 2 4

El subconjunto de los miembros con nombre también funciona de la misma manera.

R> all(foo$mymatrix[,2]==foo[[1]][,2]) [1] TRUE

Esto confirma (utilizando la función all que vio en la Sección 4.1.2) que estas dos formas de extraer la segunda columna de la matriz en foo proporcionan un resultado idéntico. Para nombrar los componentes de una lista a medida que se crea, asigne una etiqueta a cada componente en el comando list. Utilizando algunos componentes de foo, crear una nueva lista con nombre.

R> baz <- list(tom=c(foo[[2]],T,T,T,F),dick=“buenos días amigo”,harry=foo$mimatriz*2) R> baz $tom 92 Capítulo 5 [1] TRUE FALSE TRUE TRUE TRUE FALSE $dick [1] “buen día amigo” $harry [,1] [,2] [1,] 2 6 [2,] 4 8

El objeto baz contiene ahora los tres componentes con nombre tom, dick yharry.

R> names(baz) [1] “tom” “dick” “harry”

Si quieres renombrar estos miembros, puedes simplemente asignar un vector de caracteres de longitud 3 a names(baz), de la misma forma que hizo antes con foo. NOTA Cuando se utiliza la función nombres, los nombres de los componentes siempre se proporcionan y devueltos como cadenas de caracteres entre comillas dobles. Sin embargo, si especifica nombres cuando se crea una lista (dentro de la función list) o se utilizan nombres para extraer miembros con el operador dólar, los nombres se introducen sin comillas (en otras palabras, no se dan como cadenas).

#5.1.3 Anidamiento

Como ya se ha indicado, un miembro de una lista puede ser a su vez una lista. Cuando se anidan listas como ésta, es importante llevar un registro de la profundidad de cada miembro para poder o extracción posterior. Tenga en cuenta que puede añadir componentes a cualquier lista existente utilizando el operador dólar y un nuevo nombre. He aquí un ejemplo con foo y baz de anteriormente:

R> baz$bobby <- foo R> baz $tom [1] TRUE FALSE TRUE TRUE TRUE TRUE FALSE $dick [1] “buen día amigo” $harry [,1] [,2] [1,] 2 6 [2,] 4 8 $bobby Listas y marcos de datos 93 \(bobby\)mimatriz [,1] [,2] [1,] 1 3 [2,] 2 4 \(bobby\)mylogicals [1] TRUE FALSE TRUE \(bobby\)mystring [1] “¡hola a ti!”

Aquí has definido un cuarto componente a la lista baz llamado bobby. Al miembro bobby de miembro bobby se le asigna toda la lista foo. Como puedes ver imprimiendo elnuevo baz, ahora hay tres componentes en bobby. Nombres e índices están ahora en capas, y puedes usar cualquiera de ellos (o combinarlos) para recuperar miembros de la lista interna.

R> baz\(bobby\)mylogicals[1:3] [1] TRUE FALSE TRUE R> baz[[4]][[2]][1:3] [1] TRUE FALSE TRUE R> baz[[4]]]$mylogicals[1:3] [1] TRUE FALSE TRUE

Todo esto indica a R que devuelva los tres primeros elementos del vector lógico almacenado como segundo componente ([[2]], también llamado mylogicals) de la lista bobby, que a su vez es el cuarto componente de la lista baz. Mientras que sepas lo que se devuelve en cada capa de un subconjunto, puedes continuar subconjuntos según sea necesario utilizando nombres e índices numéricos. Considere la tercera de este ejemplo. La primera capa del subconjunto es baz[[4]], que es una lista con tres componentes. La segunda capa del subconjunto extrae el componente mylogicals de esa lista llamando a baz[[4]]\(mylogicals. Este componente representa un vector de longitud 4, por lo que la tercera capa de subconjunto recupera los tres primeros elementos de ese vector con la línea baz[[4]]\)mylogicals[1:3]. Las listas se utilizan a menudo para devolver la salida de diversas funciones de R. Sin embargo pueden convertirse rápidamente en objetos bastante grandes en términos de recursos del sistema para almacenar. Generalmente se recomienda que cuando se tiene un solo tipo de datos, debe limitarse a utilizar estructuras básicas de vectores, matrices o arrays para registrar y almacenar las observaciones. y almacenar las observaciones.

Ejercicio 5.1

  1. Crea una lista que contenga, en este orden, una secuencia de 20 números espaciados uniformemente entre -4 y 4. espaciados entre -4 y 4; una matriz 3 × 3 del vector lógico lógico c(F,T,T,T,F,T,T,F,F) rellenada por columnas; un vector de caracteres 94 Capítulo 5 con las dos cadenas “don” y “quijote”; y un vector factorial que contenga las observaciones c(“BAJA”, “MED”, “BAJA”, “MED”, “MED”, “ALTA”). A continuación, haga lo siguiente
  2. Extraiga los elementos de fila 2 y 1 de las columnas 2 y 3, en ese orden, de la matriz lógica.
  1. Utilice sub para sobrescribir “quijote” con “Quijote” y “don” con “Don” dentro de la lista. A continuación, utilizando la lista recién sobrescrita recién sobrescrita, concatena en la pantalla de la consola la siguiente declaración exactamente: “¡Molinos! ATACAR!” -Quijote/-
  2. Obtener todos los valores de la secuencia entre -4 y 4 que sean mayores que 1.
  3. Utilizando los cuales, determinar a qué índices del vector de factores se les asigna el nivel “MED”. tienen asignado el nivel “MED”.
  1. Cree una nueva lista con el vector de factores de (a) como un componente llamado “facs”; el vector numérico c(3,2.1,3.3,4,1.5,4.9) como un componente llamado componente denominado “nums”; y una lista anidada compuesta por los primeros tres miembros de la lista de (a) (utilice el corte de listas para obtenerla), llamada “oldlist”. A continuación, haga lo siguiente
  2. Extraiga los elementos de “facs” que correspondan a elementos de “que sean mayores o iguales que 3.
  1. Añade un nuevo miembro a la lista llamado “flags”. Este miembro debe ser un vector lógico de longitud 6, obtenido como una doble doble de la tercera columna de la matriz lógica del componente componente “oldlist”.
  2. Utilice “flags” y el operador lógico de negación ! para extraer las entradas de “num” correspondientes a FALSE.
  3. Sobrescribir el componente vectorial de cadenas de caracteres de “oldlist” con la cadena de caracteres única “Don Quijote”. 5.2 Marcos de datos Un marco de datos es la forma más natural de R de presentar un conjunto de datos con una colección de observaciones registradas para una o más variables. Al igual que las listas, los marcos de datos no tienen restricciones en cuanto a los tipos de datos de las variables; se pueden almacenar datos numéricos, datos factoriales, etcétera. datos numéricos, datos factoriales, etc. El marco de datos de R puede considerarse como una lista con algunas reglas adicionales. La distinción más importante es que en un (a diferencia de una lista), todos los miembros deben ser vectores de la misma longitud. El marco de datos es una de las herramientas más importantes y utilizadas en R para el análisis estadístico de datos. en R para el análisis estadístico de datos. En esta sección, verá cómo crear marcos de datos y conocerá sus características generales. Listas y marcos de datos 95

#5.2.1 Construcción

Para crear un marco de datos desde cero, utilice la función data.frame. Suministre datos, agrupados por variables, como vectores de la misma longitud, de la misma que construiría una lista con nombre. Considere el siguiente conjunto de datos de ejemplo: R> mydata <- data.frame(person=c(“Peter”, “Lois”, “Meg”, “Chris”, “Stewie”), age=c(42,40,17,14,1), sex=factor(c(“M”,“F”,“F”,“M”,“M”))) R> mydata persona edad sexo 1 Pedro 42 M 2 Lois 40 H 3 Meg 17 F 4 Chris 14 M 5 Stewie 1 M Aquí, has construido un marco de datos con el nombre, la edad en años y sexo de cinco individuos. El objeto devuelto debe dejar claro por qué vectores pasados a data.frame deben tener la misma longitud: los vectores de longitudes longitudes diferentes no tendrían sentido en este contexto. Si se pasan vectores de longitud vectores de longitud desigual a data.frame, R intentará reciclar los vectores más cortos para que coincidan con los más largos. vectores más cortos para que coincidan con el más largo, desviando sus datos y potencialmente asignando observaciones a la variable equivocada. Observe que los marcos de datos se imprimen en la se imprimen en la consola en filas y columnas, se parecen más a una matriz que a una lista con nombres. lista. Este estilo natural de hoja de cálculo facilita la lectura y manipulación de conjuntos de datos. de datos. Cada fila de un marco de datos se denomina registro, y cada columna es una variable. Puede extraer partes de los datos especificando las posiciones de los índices de fila y columna (como en una matriz). (como en una matriz). He aquí un ejemplo: R> mydata[2,2] [1] 40 Esto le da el elemento en la fila 2, columna 2-la edad de Lois. Ahora extrae los elementos tercero, cuarto y quinto de la tercera columna: R> mydata[3:5,3] [1] F M M Niveles: F M Esto devuelve un vector de factores con el sexo de Meg, Chris y Stewie. El siguiente extrae las columnas tercera y primera completas (en ese orden): R> mydata[,c(3,1)] sexo persona 1 M Peter 2 F Lois 3 F Meg 96 Capítulo 5 4 M Chris 5 M Stewie Esto da como resultado otro marco de datos con el sexo y el nombre de cada persona. cada persona. También puede utilizar los nombres de los vectores pasados a data.frame para acceder a las variables aunque no conozcas las posiciones de sus índices de columna, lo que puede ser útil para grandes conjuntos de datos. Se utiliza el mismo operador dólar que que utilizó para las listas con nombre de referencia de miembros. R> mydata\(edad [1] 42 40 17 14 1 También puede subconjuntar este vector devuelto: R> mydata\)edad[2] [1] 40 Esto devuelve lo mismo que la llamada anterior de mydata[2,2]. Puede informar del tamaño de un marco de datos -el número de registros y de registros y variables, de la misma forma que ha visto las dimensiones de una matriz (mostradas por primera vez en la sección 3.1.3). en la Sección 3.1.3). R> nrow(misdatos) [1] 5 R> ncol(misdatos) [1] 3 R> dim(misdatos) [1] 5 3 La función nrow recupera el número de filas (registros), ncol recupera el número de columnas (variables), y dim recupera ambos. El comportamiento por defecto de R para vectores de caracteres pasados a data.frame es convertir cada variable en un objeto factor. Observe lo siguiente: R> mydata\(persona [1] Peter Lois Meg Chris Stewie Niveles Chris Lois Meg Peter Stewie Observe que esta variable tiene niveles, lo que muestra que está siendo tratada como un factor. Pero esto no es lo que pretendía cuando definió mydata anteriormente. definió explícitamente el sexo como un factor, pero dejó a la persona como un vector de cadenas de caracteres. caracteres. Para evitar esta conversión automática de cadenas de caracteres en factores cuando utilice data.frame, establezca el argumento opcional stringsAsFactors en FALSE (de lo contrario, el valor por defecto es TRUE). La reconstrucción de mydata con esta opción tiene el siguiente aspecto así: R> mydata <- data.frame(person=c("Peter", "Lois", "Meg", "Chris", "Stewie"), age=c(42,40,17,14,1), Listas y marcos de datos 97 sex=factor(c("M","F","F","M","M")), stringsAsFactors=FALSE) R> mydata persona edad sexo 1 Pedro 42 M 2 Lois 40 H 3 Meg 17 F 4 Chris 14 M 5 Stewie 1 M R> mydata\)persona [1] “Peter” “Lois” “Meg Chris Stewie Ahora tiene persona en la forma no factorial deseada.

#5.2.2 Añadir columnas de datos y combinar marcos de datos

Supongamos que desea añadir datos a un marco de datos existente. Podría tratarse de un conjunto de un conjunto de observaciones para una nueva variable (aumentando el número de columnas), o podrían ser más registros (aumentando el número de columnas). más registros (aumentando el número de filas). Una vez más, puede utilizar algunas de las funciones puedes utilizar algunas de las funciones que ya has visto aplicadas a matrices. Recuerde las funciones rbind y cbind del apartado 3.1.2, que le permiten añadir filas y columnas, respectivamente. Las funciones rbind y cbind permiten añadir filas y columnas, respectivamente. Estas mismas funciones pueden utilizarse para ampliar marcos de datos de forma intuitiva. Por ejemplo, supongamos que tenemos otro registro que incluir en mydata. para incluir en mydata: la edad y el sexo de otro individuo, Brian. El primer paso es crear un nuevo marco de datos que contenga la información de Brian. R> newrecord <- data.frame(persona=“Brian”,edad=7, sex=factor(“M”,levels=levels(mydata$sex)))) R> newrecord persona edad sexo 1 Brian 7 M Para evitar cualquier confusión, es importante asegurarse de que los nombres de las variables y los tipos de datos coincidan con el marco de datos al que piensa añadirlos. Tenga en cuenta que para un factor, puede extraer los niveles de la variable factor existente utilizando niveles. Ahora, usted puede simplemente llamar a la siguiente: R> mydata <- rbind(mydata,newrecord). R> mydata persona edad sexo 1 Pedro 42 M 2 Lois 40 F 3 Meg 17 F 4 Chris 14 M 5 Stewie 1 M 6 Brian 7 M 98 Capítulo 5 Uso de rb