-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy path06-estructuras-datos.Rmd
577 lines (418 loc) · 22.1 KB
/
06-estructuras-datos.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
# Estructuras de datos
Las estructuras de datos son objetos que contienen datos. Cuando trabajamos con R, lo que estamos haciendo es manipular estas estructuras.
Las estructuras tienen diferentes características. Entre ellas, las que distinguen a una estructura de otra son su número de **dimensiones** y si son **homogeneas** o **hereterogeneas**.
La siguiente tabla muestra las principales estructuras de control que te encontrarás en R.
Dimensiones| Homogéneas| Heterogéneas
---- |---- |----
1 | Vector | Lista
2 | Matriz | Data frame
n | Array |
*Adaptado de Wickham (2016).*
Veamos las características de cada una de ellas.
## Vectores
Un vector es la estructura de datos más sencilla en R. Un vector es una colección de uno o más datos del mismo tipo.
Todos los vectores tienen tres propiedades:
* **Tipo**. Un vector tiene el mismo tipo que los datos que contiene. Si tenemos un vector que contiene datos de tipo numérico, el vector será también de tipo numérico. Los vectores son **atómicos**, pues sólo pueden contener datos de un sólo tipo, no es posible mezclar datos de tipos diferentes dentro de ellos.
* **Largo**. Es el número de elementos que contiene un vector. El largo es la única **dimensión** que tiene esta estructura de datos.
* **Atributos**. Los vectores pueden tener metadatos de muchos tipos, los cuales describen características de los datos que contienen. Todos ellos son incluidos en esta propiedad. En este libro no se usarán vectores con metadatos, por ser una propiedad con usos van más allá del alcance de este libro.
Cuando una estructura únicamente puede contener datos de un sólo tipo, como es el caso de los vectores, decimos que es **homogénea**, pero no implica que necesariamente sea **atómica**. Regresaremos sobre esto al hablar de matrices y arrays.
Como los vectores son la estructura de datos más sencilla de R, datos simples como el número **3**, son en realidad vectores. En este caso, un vector de tipo numérico y largo igual a 1.
```{r, echo=TRUE}
3
```
Verificamos que el **3** es un vector con la función `is.vector()`.
```{r, echo=TRUE}
is.vector(3)
```
Y usamos la función `length()` para conocer su largo.
```{r, echo=TRUE}
length(3)
```
Lo mismo ocurre con los demás tipos de datos, por ejemplo, con cadenas de texto y datos lógicos.
```{r, echo=TRUE}
is.vector("tres")
is.vector(TRUE)
```
### Creación de vectores
Creamos vectores usando la función `c()` (*combinar*).
Llamamos esta función y le damos como argumento los elementos que deseamos combinar en un vector, separados por comas.
```{r, echo=TRUE}
# Vector numérico
c(1, 2, 3, 5, 8, 13)
# Vector de cadena de texto
c("arbol", "casa", "persona")
# Vector lógico
c(TRUE, TRUE, FALSE, FALSE, TRUE)
```
Si deseamos agregar un elemento a un vector ya existente, podemos hacerlo combinando nuestro vector original con los elementos nuevos y asignando el resultado a nuestro vector original.
```{r, echo=TRUE}
mi_vector <- c(TRUE, FALSE, TRUE)
mi_vector <- c(mi_vector, FALSE)
mi_vector
```
Naturalmente, podemos crear vectores que son combinación de vectores.
```{r, echo=TRUE}
mi_vector_1 <- c(1, 3, 5)
mi_vector_2 <- c(2, 4, 6)
mi_vector_3 <- c(mi_vector_1, mi_vector_2)
mi_vector_3
```
Si intentamos combinar datos de diferentes tipos en un mismo vector, R realizará coerción automáticamente. El vector resultante será del tipo más flexible entre los datos que contenga, siguiendo las reglas de ***coerción***.
Creamos un vector numérico.
```{r, echo=TRUE}
mi_vector <- c(1, 2, 3)
class(mi_vector)
```
Si intentamos agregar un dato de tipo cadena de texto, nuestro vector ahora será de tipo cadena de texto.
```{r}
mi_vector_nuevo <- c(mi_vector, "a")
class(mi_vector_nuevo)
```
Como las cadenas de texto son el tipo de dato más flexible, siempre que creamos un vector que incluye un dato de este tipo, el resultado será un vector de texto.
```{r}
mi_vector_mezcla <- c(FALSE, 2, "tercero", 4.00)
class(mi_vector_mezcla)
```
Podemos crear vectores de secuencias numéricas usando `:`. De un lado de los dos puntos escribimos el número de inicio de la secuencia y del otro el final.
Por ejemplo, creamos una secuencia del 1 al 10.
```{r dos puntos, echo=TRUE}
1:10
```
También podemos crear una secuencia del 10 al 1.
```{r dos puntos dec, echo=TRUE}
10:1
```
Las secuencias creadas con `:` son consecutivas con incrementos o decrementos de 1. Estas secuencias pueden empezar con cualquier número, incluso si este es negativo o tiene cifras decimales
```{r dos puntos otros, echo=TRUE}
# Número negativo
-43:-30
# Número con cifras decimales
67.23:75
```
Si nuestro número de inicio tiene cifras decimales, estas serán respetadas al hacer los incrementos o decrementos de uno en uno. En contraste, si es nuestro número de final el que tiene cifras decimales, este será redondeado.
```{r dos puntos dec 2, echo=TRUE}
# Se conservan los decimales del inicio
-2.48:2
56.007:50
# Se redondean los decimales del final
166:170.05
968:960.928
```
### Vectorización de operaciones
Existen algunas operaciones al aplicarlas a un vector, se aplican a cada uno de sus elementos. A este proceso le llamamos **vectorización**.
Las operaciones aritméticas y relacionales pueden vectorizarse. Si las aplicamos a un vector, la operación se realizará para cada uno de los elementos que contiene.
Por ejemplo, creamos un vector numérico.
```{r mi_vector_vectorizacion, echo=TRUE}
mi_vector <- c(2, 3, 6, 7, 8, 10, 11)
```
Si aplicamos operaciones aritméticas, obtenemos un vector con un resultado por cada elemento.
```{r vecotirzacion_arit, echo=TRUE}
# Operaciones aritméticas
mi_vector + 2
mi_vector * 2
mi_vector %% 2
```
Al aplicar operaciones relacionales, obtenemos un vector de `TRUE`y `FALSE`, uno para cada elemento comparado.
```{r vectorizacion_rela, echo=TRUE}
mi_vector > 7
mi_vector < 7
mi_vector == 7
```
Esta manera de aplicar una operación es muy eficiente. Comparada con otros procedimientos, requiere de menos tiempo de cómputo, lo cual a veces es considerable, en particular cuando trabajamos con un número grande de datos.
Aunque el nombre de este proceso es **vectorización**, también funciona, en ciertas circunstancias, para otras estructuras de datos.
## Matrices y arrays
Las matrices y arrays pueden ser descritas como **vectores multidimensionales**. Al igual que un vector, únicamente pueden contener datos de un sólo tipo, pero además de largo, tienen más dimensiones.
En un sentido estricto, las matrices son una caso especial de un array, que se distingue por tener **específicamente dos dimensiones**, un "largo"" y un "alto". Las matrices son, por lo tanto, una estructura con forma rectangular, con renglones y columnas.
Como las matrices son usadas de manera regular en matemáticas y estadística, es una estructura de datos de uso común en R común y en la que nos enfocaremos en este libro.
Los arrays, por su parte, pueden tener un número arbitrario de dimensiones. Pueden ser cubos, hipercubos y otras formas. Su uso no es muy común en R, aunque a veces es deseable contar con objetos n-dimensionales para manipular datos. Como los arrays tienen la restricción de que todos sus datos deben ser del mismo tipo, no importando en cuántas dimensiones se encuentren, esto limita sus usos prácticos.
En general, es preferible usar listas en lugar de arrays, una estructura de datos que además tienen ciertas ventajas que veremos más adelante.
### Creación de matrices
Creamos matrices en R con la función `matrix()`. La función `matrix()` acepta dos argumentos, `nrow` y `ncol`. Con ellos especificamos el número de renglones y columnas que tendrá nuestra matriz.
```{r, echo=TRUE}
# Un vector numérico del uno al doce
1:12
# matrix() sin especificar renglones ni columnas
matrix(1:12)
# Tres renglones y cuatro columnas
matrix(1:12, nrow = 3, ncol = 4)
# Cuatro columnas y tres columnas
matrix(1:12, nrow = 4, ncol = 3)
# Dos renglones y seis columnas
matrix(1:12, nrow = 4, ncol = 3)
```
Los datos que intentemos agrupar en una matriz serán acomodados en orden, de arriba a abajo, y de izquierda a derecha, hasta formar un rectángulo.
Si multiplicamos el número de renglones por el número de columnas, obtendremos el número de celdas de la matriz. En los ejemplo anteriores, el número de celdas es igual al número de elementos que queremos acomodar, así que la operación ocurre sin problemas.
Cuando intentamos acomodar un número diferente de elementos y celdas, ocurren dos cosas diferentes.
Si el número de elementos es mayor al número de celdas, se acomodarán todos los datos que sean posibles y los demás se omitirán.
```{r, echo=TRUE}
matrix(1:12, nrow = 3, ncol = 3)
```
Si, por el contrario, el número de celdas es mayor que el número de elementos, estos se **reciclaran**. En cuanto los elementos sean insuficientes para acomodarse en las celdas, R nos devolverá una advertencia y se empezaran a usar los elementos a partir del primero de ellos
```{r, echo=TRUE}
matrix(1:12, nrow = 5, ncol = 4)
```
Otro procedimiento para crear matrices es la unión vectores con las siguientes funciones:
* `cbind()` para unir vectores, usando cada uno como una columna.
* `rbind()` para unir vectores, usando cada uno como un renglón.
De este modo podemos crear cuatro vectores y unirlos para formar una matriz. Cada vector será un renglón en esta matriz.
Creamos cuatro vectores, cada uno de largo igual a cuatro.
```{r, echo = TRUE}
vector_1 <- 1:4
vector_2 <- 5:8
vector_3 <- 9:12
vector_4 <- 13:16
```
Usamos `rbind()` para crear un matriz, en la que cada vector será un renglón.
```{r, echo = TRUE}
matriz <- rbind(vector_1, vector_2, vector_3, vector_4)
# Resultado
matriz
```
Si utilizamos `cbind()`, entonces cada vector será una columna.
```{r, echo = TRUE}
matriz <- cbind(vector_1, vector_2, vector_3, vector_4)
# Resultado
matriz
```
Al igual que con `matrix()`, los elementos de los vectores son reciclados para formar una estructura rectangular y se nos muestra un mensaje de advertencia.
```{r, echo = TRUE}
# Elementos de largo diferente
vector_1 <- 1:2
vector_2 <- 1:3
vector_3 <- 1:5
matriz <- cbind(vector_1, vector_2, vector_3)
# Resultado
matriz
```
Finalmente, las matrices pueden contener `NA`s.
Creamos dos vectores con un `NA` en ellos.
```{r, echo=TRUE}
vector_1 <- c(NA, 1, 2)
vector_2 <- c(3, 4, NA)
```
Creamos una matriz con `rbind()`.
```{r}
matriz <- rbind(vector_1, vector_2)
# Resultados
matriz
```
Como `NA` representa datos perdidos, puede estar presente en compañía de todo tipo de de datos.
### Propiedades de las matrices
No obstante que las matrices y arrays son estructuras que sólo pueden contener un tipo de datos, no son atómicas. Su clase es igual a **matriz (matrix)** o **array** según corresponda.
Verificamos esto usando la función `class()`.
```{r, echo=TRUE}
mi_matriz <- matrix(1:10)
class(mi_matriz)
```
Las matrices y arrays pueden tener más de una dimensión.
Obtenemos el número de dimensiones de una matriz o array con la función `dim()`. Esta función nos devolverá varios números, cada uno de ellos indica la cantidad de elementos que tiene una dimensión.
```{r, echo=TRUE}
mi_matriz <- matrix(1:12, nrow = 4, ncol = 3)
dim(mi_matriz)
```
Cabe señalar que si usamos `dim()` con un vector, obtenemos `NULL`. Esto ocurre con todos los objetos unidimensionales
```{r, echo=TRUE}
mi_vector <- 1:12
dim(mi_vector)
```
Finalmente, las operaciones aritméticas también son vectorizadas al aplicarlas a una matriz. La operación es aplicada a cada uno de los elementos de la matriz.
Creamos una matriz.
```{r, echo=TRUE}
mi_matriz <- matrix(1:9, nrow = 3, ncol = 3)
# Resultado
mi_matriz
```
Intentemos sumar, multiplicar y elevar a la tercera potencia.
```{r}
# Suma
mi_matriz + 1
# Multiplicación
mi_matriz * 2
# Potenciación
mi_matriz ^ 3
```
Si intentamos vectorizar una operación utilizando una matriz con `NA`s, esta se aplicará para los elementos válidos, devolviendo `NA` cuando corresponda.
Creamos una matriz con `NA`s.
```{r, echo=TRUE}
vector_1 <- c(NA, 2, 3)
vector_2 <- c(4, 5, NA)
matriz <- rbind(vector_1, vector_2)
# Resultado
matriz
```
Intentamos dividir sus elementos entre dos.
```{r, echo=T}
matriz / 2
```
Finalmente, podemos usar la función `t()` para transponer una matriz, es decir, rotarla 90°.
Creamos una matriz con tres renglones y dos columnas.
```{r, echo=TRUE}
matriz <- matrix(1:6, nrow = 3)
# Resultado
matriz
```
Usamos `t()` para transponer.
```{r, echo=TRUE}
matriz_t <- t(matriz)
# Resultado
matriz_t
```
Obtenemos una matriz con dos renglones y dos columnas.
## Data frames
Los data frames son estructuras de datos de dos dimensiones (rectangulares) que pueden contener datos de diferentes tipos, por lo tanto, son heterogéneas. Esta estructura de datos es la más usada para realizar análisis de datos y seguro te resultará familiar si has trabajado con otros paquetes estadísticos.
Podemos entender a los data frames como una versión más flexible de una matriz. Mientras que en una matriz todas las celdas deben contener datos del mismo tipo, los renglones de un data frame admiten datos de distintos tipos, pero sus columnas conservan la restricción de contener datos de un sólo tipo.
En términos generales, los renglones en un data frame representan casos, individuos u observaciones, mientras que las columnas representan atributos, rasgos o variables.
Por ejemplo, así lucen los primeros cinco renglones del objeto **iris**, el famoso conjunto de datos *Iris de Ronald Fisher*, que está incluido en todas las instalaciones de R.
```{r, echo=FALSE}
head(iris, 5)
```
Los primeros cinco renglones corresponden a cinco casos, en este caso flores. Las columnas son variables con los rasgos de cada flor: largo y ancho de sépalo, largo y ancho de pétalo, y especie.
Para crear un data frame usamos la función `data.frame()`. Esta función nos pedirá un número de vectores igual al número de columnas que deseemos. Todos los vectores que proporcionemos deben tener el mismo largo.
Esto es muy importante: **Un data frame está compuesto por vectores**.
Más adelante se hará evidente porque esta característica de un data frame es sumamente importante y también, cómo podemos sacarle provecho.
Además, podemos asignar un nombre a cada vector, que se convertirá en el nombre de la columna. Como todos los nombres, es recomendable que este sea claro, no ambiguo y descriptivo.
```{r, echo = TRUE}
mi_df <- data.frame(
"entero" = 1:4,
"factor" = c("a", "b", "c", "d"),
"numero" = c(1.2, 3.4, 4.5, 5.6),
"cadena" = as.character(c("a", "b", "c", "d"))
)
mi_df
# Podemos usar dim() en un data frame
dim(mi_df)
# El largo de un data frame es igual a su número de columnas
length(mi_df)
# names() nos permite ver los nombres de las columnas
names(mi_df)
# La clase de un data frame es data.frame
class(data.frame)
```
Si los vectores que usamos para construir el data frame no son del mismo largo, los datos **no se reciclaran**. Se nos devolverá un error.
```{r, echo=TRUE, error=TRUE}
data.frame(
"entero" = 1:3,
"factor" = c("a", "b", "c", "d"),
"numero" = c(1.2, 3.4, 4.5, 5.6),
"cadena" = as.character(c("a", "b", "c", "d"))
)
```
También podemos coercionar esta matriz a un data frame.
Creamos una matriz.
```{r}
matriz <- matrix(1:12, ncol = 4)
```
Usamos `as.data.frame()` para coercionar una matriz a un data frame.
```{r}
df <- as.data.frame(matriz)
```
Verificamos el resultado
```{r}
class(df)
# Resultado
df
```
### Propiedades de un data frame
Al igual que con una matriz, si aplicamos una operación aritmética a un data frame, esta se vectorizará.
Los resultados que obtendremos dependerán del tipo de datos de cada columna. R nos devolverá todas las advertencias que ocurran como resultado de las operaciones realizadas, por ejemplo, aquellas que hayan requerido una coerción.
```{r, echo=TRUE}
mi_df <- data.frame(
"entero" = 1:4,
"factor" = c("a", "b", "c", "d"),
"numero" = c(1.2, 3.4, 4.5, 5.6),
"cadena" = as.character(c("a", "b", "c", "d"))
)
mi_df * 2
```
## Listas
Las listas, al igual que los vectores, son estructuras de datos unidimensionales, sólo tienen largo, pero a diferencia de los vectores cada uno de sus elementos puede ser de diferente tipo o incluso de diferente clase, por lo que son estructuras heterogéneas.
Podemos tener listas que contengan datos atómicos, vectores, matrices, arrays, data frames u otras listas. Esta última característica es la razón por la que una lista puede ser considerada un vector recursivo, pues es un objeto que puede contener objetos de su misma clase.
Para crear una lista usamos la función `list()`, que nos pedirá los elementos que deseamos incluir en nuestra lista. Para esta estructura, no importan las dimensiones o largo de los elementos que queramos incluir en ella.
Al igual que con un data frame, tenemos la opción de poner nombre a cada elemento de una lista.
Por último, no es posible vectorizar operaciones aritméticas usando una lista, se nos devuelve un error como resultado.
```{r, echo = TRUE, error=TRUE}
mi_vector <- 1:10
mi_matriz <- matrix(1:4, nrow = 2)
mi_df <- data.frame("num" = 1:3, "let" = c("a", "b", "c"))
mi_lista <- list("un_vector" = mi_vector, "una_matriz" = mi_matriz, "un_df" = mi_df)
mi_lista
```
Creamos una lista que contiene otras listas.
```{r, echo=TRUE}
lista_recursiva <- list("lista1" = mi_lista, "lista2" = mi_lista)
# Resultado
lista_recursiva
```
### Propiedades de una lista
Una lista es unidimensional, sólo tiene largo.
El largo de una lista es igual al número de elementos que contiene, sin importar de qué tipo o clase sean. Usamos la lista recursiva que creamos en la sección anterior para ilustrar esto.
```{r, echo=TRUE}
length(lista_recursiva)
```
Dado que una lista siempre tiene una sola dimensión, la función `dim()` nos devuelve `NULL`.
```{r, echo=TRUE}
dim(lista_recursiva)
```
Las listas tienen clase **list**, sin importar qué elementos contienen.
```{r, echo=TRUE}
class(lista_recursiva)
```
Finalmente, no es posible vectorizar operaciones aritméticas usando listas. Al intentarlo nos es devuelto un error.
```{r, echo=TRUE, error=TRUE}
mi_lista / 2
```
Si deseamos aplicar una función a cada elemento de una lista, usamos `lapply()`, como veremos en el [capítulo 10](#apply).
## Coerción
Al igual que con los datos, cuando intentamos hacer operaciones con una estructura de datos, R intenta coercionarla al tipo apropiado para poder llevarlas a cabo con éxito.
También podemos usar alguna de las funciones de la familia `as()` coercionar de un tipo de estructura de datos. A continuación se presentan las más comunes.
Función | Coerciona a | Coerciona exitosamente a
---- |---- | ----
`as.vector()` | Vector | Matrices
`as.matrix()` | Matrices | Vectores, Data frames
`as.data.frame()` | Data frame | Vectores, Matrices
`as.list()` | Lista | Vectores, Matrices, Data frames
Como podrás ver, las estructuras de datos más sencillas, (unidimensionales, homogéneas) pueden ser coercionadas a otras más complejas (multidimensionales, heterogéneas), pero la operación inversa casi nunca es posible.
Veamos algunos ejemplos.
Creamos un vector, una matriz, un data frame y una lista.
```{r crear_estructuras, echo=TRUE}
mi_vector <- c("a", "b", "c")
mi_matriz <- matrix(1:4, nrow = 2)
mi_df <- data.frame("a" = 1:2, "b" = c("a", "b"))
mi_lista <- list("a" = mi_vector, "b" = mi_matriz, "c" = mi_df)
```
Intentemos coercionar a vector con `as.vector()`.
```{r as_vector, echo=TRUE}
as.vector(mi_matriz)
as.vector(mi_df)
as.vector(mi_lista)
```
La coerción que intentamos sólo tuvo éxito para una matriz. Para data frame y lista, nos devolvió los mismos objetos.
Nota que `as.vector()` **no devolvió un error o una advertencia a pesar de que no tuvo éxito** al coercionar, en este caso un data frame o una lista. Esto es importante, pues no puedes confiar que `as.vector()` tuvo éxito porque corrió sin errores, es necesaria una verificación adicional. Como R intenta coercionar automáticamente, esto puede producir resultados inesperados si no tenemos cuidado.
Intentemos coercionar a matriz con `as.matrix()`.
```{r, echo=TRUE}
as.matrix(mi_vector)
as.matrix(mi_df)
as.matrix(mi_lista)
```
El vector fue coercionado a una matriz con una sola columna.
Por su parte, al correr la función con un data frame, coercionamos también todos los datos que contiene, siguiendo las reglas de coerción de tipos de dato que vimos en el [capítulo 4](## coercion).
Al coercionar una lista a una matriz, efectivamente obtenemos un objeto de este tipo, sin embargo perdemos toda la información que contiene, por lo tanto, no podemos considerar que esta es una coerción exitosa. Del mismo modo que con `as.vector()`, no nos es mostrado ningún error ni advertencia.
Intentemos coercionar a matriz con `as.data.frame()`.
```{r as_dataframe, echo=TRUE, error=TRUE}
as.data.frame(mi_vector)
as.data.frame(mi_matriz)
as.data.frame(mi_lista)
```
Tuvimos éxito al coercionar vectores y matrices.
El vector, al igual que cuando fue coercionado a matriz, devolvió como resultado un objeto con una sola columna, mientras que la matriz conservó sus renglones y columnas.
En este caso, al intentar la coerción de lista a data frame, obtenemos un error. Esta es la única situación en la que esto ocurre utilizando las funciones revisadas en esta sección.
Por último, intentemos coercionar a matriz con `as.list()`.
```{r as_list, echo=TRUE}
as.list(mi_vector)
as.list(mi_matriz)
as.list(mi_df)
```
Dado que las listas son el tipo de objeto más flexible de todos, hemos tenido éxito en todos los casos con nuestra coerción.
Nota que para los vectores y matrices, cada uno de los elementos es transformado en un elemento dentro de la lista resultante. Si tuviéramos una matriz con cuarenta y ocho celdas, obtendríamos una lista con ese mismo número de elementos.
En cambio, para un data frame, el resultado es una lista, en la que cada elemento contiene los datos de una columna del data frame original. Un data frame con diez columnas resultará en una lista de diez elementos.
Conocer cómo ocurre la coerción de estructuras de datos te ayudará a entender mejor algunos resultados devueltos por funciones de R, además de que te facilitará la manipulación y procesamiento de datos.