6.5 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, homogeneas) pueden ser coercionadas a otras más complejas (multidimensionales, heterogeneas), pero la operación inversa casi nunca es posible.

Veamos algunos ejemplos.

Creamos un vector, una matriz, un data frame y una lista.

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().

as.vector(mi_matriz)
## [1] 1 2 3 4
as.vector(mi_df)
##   a b
## 1 1 a
## 2 2 b
as.vector(mi_lista)
## $a
## [1] "a" "b" "c"
## 
## $b
##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4
## 
## $c
##   a b
## 1 1 a
## 2 2 b

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().

as.matrix(mi_vector)
##      [,1]
## [1,] "a" 
## [2,] "b" 
## [3,] "c"
as.matrix(mi_df)
##      a   b  
## [1,] "1" "a"
## [2,] "2" "b"
as.matrix(mi_lista)
##   [,1]       
## a Character,3
## b Integer,4  
## c List,2

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.

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().

as.data.frame(mi_vector)
##   mi_vector
## 1         a
## 2         b
## 3         c
as.data.frame(mi_matriz)
##   V1 V2
## 1  1  3
## 2  2  4
as.data.frame(mi_lista)
## Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, : arguments imply differing number of rows: 3, 2

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().

as.list(mi_vector)
## [[1]]
## [1] "a"
## 
## [[2]]
## [1] "b"
## 
## [[3]]
## [1] "c"
as.list(mi_matriz)
## [[1]]
## [1] 1
## 
## [[2]]
## [1] 2
## 
## [[3]]
## [1] 3
## 
## [[4]]
## [1] 4
as.list(mi_df)
## $a
## [1] 1 2
## 
## $b
## [1] a b
## Levels: a b

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 tuvieramos 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.