Inspección de variables y el espacio de trabajo
Todas las variables en R tienen una clase, que te dice qué tipos de variables son. Por ejemplo, la mayoría de los números tienen clase numeric y los valores lógicos tienen la clase logic. El tipo de datos más pequeño en R es un vector.
Podemos averiguar la clase de una variable utilizando class(variable):
class(c(TRUE, FALSE))
[1] "logical"
Las variables también tienen un tipo de almacenamiento interno (accedido a través de typeof), un modo (mode) y un modo de almacenamiento (storage.mode).
Los tipos, modos y modos de almacenamiento existen en su mayoría para propósitos heredados, por lo que en la práctica sólo necesitarás usar class de un objeto.
set.seed(2)
x <- 1:10
typeof(x)
[1] "integer"
y <- x/5 + rnorm(10)
typeof(y)
[1] "double"
g <- lm(y ~ x)
typeof(g)
[1] "list"
R contiene tres clases diferentes de variable numérica: numeric para valores en coma flotante, integer para los enteros y complex para los números complejos. Podemos decir cuál es cuál examinando la clase de la variable:
class(sqrt(1:10))
[1] "numeric"
class(4L)
[1] "integer"
class(1 + 2i)
[1] "complex"
class(0.5:4.5)
[1] "numeric"
Además de las tres clases numéricas y la clase lógica que hemos visto, hay tres clases más de vectores: caracter para almacenar el texto, factors para almacenar datos categóricos y raw para almacenar datos binarios.
class(c("ella", "es", "bella", "ella", "es", "una", "estrella"))
[1] "character"
R tiene una solución más sofisticada para datos categóricos utilizando factores que son números enteros con etiquetas:
genero <- factor(c("masculino", "femenino", "femenino", "masculino", "femenino"))
El contenido del factor se parece mucho a su equivalente de caracteres: obtiene etiquetas legibles para cada valor que se limitan a valores específicos conocidos como los niveles del factor:
nlevels(genero)
[1] 2
Por defecto, los niveles de factor se asignan alfabéticamente. Los valores deL factor se almacenan como números enteros en lugar de caracteres. Podemos ver esto más claramente usando as.integer:
as.integer(genero)
[1] 2 1 1 2 1
La clase raw almacena vectores de bytes raw. Cada byte está representado por un valor hexadecimal de dos dígitos. Estos se utilizan principalmente para almacenar el contenido de archivos binarios importados. Los números enteros 0 a 255 se pueden convertir en raw utilizando as.raw. Para las cadenas, as.raw no funciona, en este caso se debe usar charToRaw en su lugar:
as.raw(1:5)
[1] 01 02 03 04 05
letra <- charToRaw("R!")
letra
[1] 52 21
class(letra)
[1] "raw"
Además de las clases de vectores mencionadas, existen muchos otros tipos de variables, por ejemplo las matrices contienen datos multidimensionales, y las matrices con la clase matrix son un caso especial de matrices bidimensionales.
x <- matrix( c(6,7), nrow=2 )
class(x)
[1] "matrix"
Llamar a la función class es útil para examinar interactivamente las variables en el prompt de comandos, pero si queremos conocer el tipo de un objeto , es mejor usar la función is o una de sus variantes específicas de clase.
En una situación típica, nuestra prueba se verá como:
if(!is(x, "alguna_clase"))
{
...
}
La mayoría de las clases comunes tienen sus propias funciones is.* y llamarlas normalmente es un poco más eficiente que usar la función general is.
Por ejemplo:
is.character("rojo verde, amarillo fresa")
[1] TRUE
is.numeric(3L)
[1] TRUE
is.logical(FALSE)
[1] TRUE
is.list(list(a = 1, b = 2))
[1] TRUE
is.integer(3)
[1] FALSE
La función is.numeric devuelve TRUE para enteros así como valores de punto flotante. Si queremos probar sólo números de coma flotante, entonces debemos usar is.double. Sin embargo, esto no suele ser necesario, ya que R está diseñado para que los valores de punto flotante y enteros se puedan usar de forma más o menos intercambiable. Si se agrega el sufijo L el número se convierte en un entero.
is.integer(2L)
[1] TRUE
Podemos ver una lista completa de todas las funciones is del paquete base con el siguiente código:
ls(pattern = "^is", baseenv())
A veces deseamos cambiar el tipo de un objeto. Esto se llama casting y la mayoría de funciones is* tienen una función correspondiente as* para lograrlo.
Las funciones especializadas como as* deben ser usadas sobre as cuando estén disponibles, ya que son generalmente más eficientes y a menudo contienen una lógica adicional específica para cada clase.
x <- "123.456"
as(x, "numeric")
[1] 123.456
as.numeric(x)
[1] 123.456
Siempre que hayamos hecho un cálculo o el nombre de una variable en la consola de R, el resultado se imprime. Esto sucede porque R llama implícitamente al método print del objeto.
Dentro de bucles o funciones, la impresión automática no ocurre, por lo que tenemos que llamar explícitamente a print:
vector1 <- c(1, 8, 27, 64)
for(i in vector1) i # no se imprime
for(i in vector1) print(i)
[1] 1
[1] 8
[1] 27
[1] 64
Es útil algún tipo de resumen del objeto. La función summary hace exactamente eso, dando la información apropiada para diferentes tipos de datos. Las variables numéricas se resumen con la media, mediana y algunos cuantiles.
num <- runif(30)
summary(num)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.01041 0.19470 0.49537 0.51163 0.81035 0.98173
Los vectores categóricos y lógicos se resumen por los conteos de cada valor. En este ejemplo, letters es una constante incorporada que contiene los valores en minúsculas de a a la z (LETTERS contiene los equivalentes en mayúsculas, A a Z).
fac <- factor(sample(letters[1:6], 30, replace = TRUE))
summary(fac)
a b c d e f
4 8 4 3 6 5
En este caso, se presenta el conteo de valores en un muestreo aleatorio con replace de la función sample:
bool <- sample(c(TRUE, FALSE, NA), 30, replace = TRUE)
summary(bool)
Mode FALSE TRUE NA's
logical 12 10 8
Los objetos multidimensionales, como matrices y data frames, se resumen en columnas. En un data frame de 30 filas y objetos más grandes es necesario reducir la información, usando la función head que se puede utilizar para mostrar sólo las primeras filas (seis por defecto):
dfr <- data.frame(num, fac, bool)
summary(dfr)
num fac bool
Min. :0.01041 a:4 Mode :logical
1st Qu.:0.19470 b:8 FALSE:12
Median :0.49537 c:4 TRUE :10
Mean :0.51163 d:3 NA's :8
3rd Qu.:0.81035 e:6
Max. :0.98173 f:5
La función str muestra la estructura del objeto. No es tan interesante para los vectores, pero str es muy útil para los data frames y listas anidadas:
str(dfr)
'data.frame': 30 obs. of 3 variables:
$ num : num 0.662 0.388 0.837 0.151 0.347 ...
$ fac : Factor w/ 6 levels "a","b","c","d",..: 1 1 5 6 2 5 5 6 4 5 ...
$ bool: logi FALSE NA TRUE FALSE TRUE NA ...
La función unclass se puede utilizar para evitar que en la muestra de un objeto, se pierda información útil, permitiendo ver cómo se construye una variable.
unclass(fac)
[1] 1 1 5 6 2 5 5 6 4 5 5 6 4 2 6 3 3 3 2 1 2 2 1 2 2 5 2 6 3 4
attr(,"levels")
[1] "a" "b" "c" "d" "e" "f"
Es útil saber que la función attributes proporciona una lista de todos los atributos que pertenecen a un objeto:
attributes(fac)
Es bueno saber los nombres de las variables que hemos creado y lo que contienen. Para enumerar los nombres de las variables existentes, se utiliza la función ls. Este nombre lleva el nombre del comando Unix equivalente y sigue la misma convención: por defecto, los nombres de las variables que comienzan con un . están escondidos. Para verlos, pase el argumento all.names = TRUE:
r <- 1
b <- "Jessica"
c <- TRUE
ls()
[1] "b" "bool" "c" "dfr" "fac" "g" "genero"
[8] "i" "letra" "num" "r" "vector1" "x" "y"
Podemos ver la estructura de nuestras variables usando ls.str, que es muy útil durante las sesiones de depuración. browseEnv muestra una página HTML en nuestro navegador web con toda esa información:
browseEnv()
Podemos limpiar nuestro espacio de trabajo, usando la función rm para eliminar variables:
rm(r, c)
ls()
[1] "b" "bool" "dfr" "fac" "g" "genero" "i"
[8] "letra" "num" "vector1" "x" "y"