R trabaja con diferentes tipos de datos, con características propias; por ejemplo, algunas operaciones sólo pueden realizarse sobre datos específicos. En este apartado se revisan los tipos de datos más comunes en R y sus propiedades, así como la conversión (coerción) entre unos tipos y otros.

1 Datos más comunes

Los tipos de datos de uso más común en R son los siguientes.

Tipo Ejemplo Nombre en inglés
Entero 1 integer
Numérico 1.3 numeric
Cadena de texto “uno” character
Factor uno factor
Lógico TRUE logical
Perdido NA NA
Vacio NULL null
Fechas 01/02/03 dates

Tipos de datos en R

Además de estos tipos, en R también contamos con datos complejos numéricos complejos (con una parte real y una imaginaria), raw (bytes) etc. Estos tipos tiene aplicaciones muy específicas y no son de interés en esta asignatura.

2 Características de estos datos.

k <- 1                               
k                                   # Cuando asignamos 1 a k, por defecto es un dato numérico.

Podemos preguntar al sistema por el tipo de datos

class(k)                            # Qué tipo de datos es                
is.integer(k)                       # Preguntamos al sistema si es un tipo de dato específico
k <- as.integer(k)                  # Coerción: podemos transformar un dato numerico en integer

Recursos adicionales:

is.integer(k)                       # Pregunta al sistema de nuevo 
as.integer(3.14)                    # Convertimos un valor numérico en "integer"
as.integer("5.27")                                                              
as.integer("Joe")                   # No es posible transformar caracteres en integer
as.integer(TRUE)                    # Valor numérico de TRUE=1
as.integer(FALSE)                   # Valor numérico de FALSE=0
x <- 10.5       
x                                                                 
class(x)                           # Tipo de dato al que pertenece x 
fname <- "Juan"
lname <-"Sinmiedo"                        # Las variables alfanuméricas se escriben entre comillas
paste(fname, lname)                       # Dos variables character encadenadas con la función paste

sprintf("%s tiene %d euros", "Juan", 100)    # OPCIÓN 1: Creación de relaciones de variables alfanuméricas 

nombres <-  c("Pepito","Juanito")            # OPCIÓN 2: Creación de relaciones de variables alfanuméricas 
dinero <- c(100, 200)
sprintf("%s tiene %d euros", nombres, dinero)

Este es el tipo de datos más flexible de R, pues una cadena de texto puede contener letras, números, espacios, signos de puntuación y símbolos especiales. Por ejemplo, creando una cadena con todos los caracteres entre el 3 y el 12, eliminando los demás.

substr("María tiene una pelota roja.",       
       start=3, 
       stop=12)                                                                 

También es posible reemplazar la primera aparición de la cadena “pelota” por “balón”

sub("pelota", "balón", "María tiene una pelota roja.")     
help("sub")

Y por último, podemos convertir cualquier valor en “carácter” con la función as.character().

z <- as.character(3.14)            
z                                                               
class(z)                                                                         
ciudades <- c("Madrid","Palma","Madrid","Madrid","Barcelona","Palma","Madrid","Madrid")   
ciudades
ciudades.factor <- factor(ciudades)
levels(ciudades.factor)                     # Valores diferentes de la variable ciudades.factor
ciudades.factor

# Ejemplo 1 desarrollado

S <- c("M","M","F","M","F","F","F","M","M","F")       # Vector con caracteres sin significado

Sex <- as.factor(S)                                   # Posibilidad 1 de conversión a factor
Sex
Sex2 <- factor(S)                                     # Posibilidad 2 de conversión a factor
Sex2
Sex3 <- factor(S, 
               levels=c("M","F","B"),                 #  Añadimos niveles en el orden en el que los incluimos en el vector; podríamos añadir un nuevo nivel, aunque en realidad no aparece en los datos originales
               labels=c("Masc","Fem","Bisex"))                                  # Añadimos las estiquetas de esos niveles
Sex3

levels(Sex)                                                                     # Para obtener los niveles de un factor
levels(Sex3)

# Ejemplo 2

Notas <- factor(c(1,2,2,3,1,3,2,4,2,3,4,2))
Notas
levels(Notas) <- c("Muy.mal","Mal","Bien","Muy.bien")                           # Cambiamos los nombres de los niveles de un factor
Notas

Notas_2niv <- Notas
levels(Notas_2niv) <- c("Mal","Mal","Bien","Bien")
Notas_2niv

Notas <- ordered(Notas,                                                         # Si el orden de los niveles es relevante es conveniente definir el factor como ordenado (variable cualitativa ordinal)
                 levels=c("Muy.mal","Mal","Bien","Muy.bien"))
Notas

# Generación automática de factores y niveles: función gl(n, k, labels)
v <- gl(3,                                                                      # Número de niveles (valores)
        4,                                                                      # Número de casos que queremos crear
        labels = c("Santander", "Torrelavega","Reinosa"))                       # Etiquetas que corresponden al número de niveles (si n=3 tiene que haber 3 etiquetas)           
print(v)
v
# Convertir una cadena de caracteres en una fecha 
a <- as.Date("01/02/03", 
             format="%y/%m/%d") 

# Calcular la diferencia en días entre dos fechas 
b <- as.Date("01/02/03", 
             format="%y/%d/%m") 
a - b 

# Secuencia de fechas desde Enero 2005 a Julio 2005 mes a mes 
seq(as.Date("2005-01-01"),                                                      # Fecha inicial
    as.Date("2005-07-01"),                                                      # Fecha final
    by="month")                                                                 # Periodicidad

# Fecha actual + 15 dias 
Sys.Date() + 15 

# Convertir una fecha en una cadena con un formato determinado 
format(Sys.Date(), 
       format="%A, %d %B %Y") 

# Extraer el mes 
format(Sys.Date(), 
       format="%m" ) 

# Recorrer la secuencia 
dates <- seq(as.Date("2005-01-01"), as.Date("2005-07-01"), by="month") 
for (i in 1:length(dates)) { 
  d = as.Date(as.character(dates[i]))                                           # Hay que convertir o solo visualizaremos un numero 
  cat(paste(d, "\n", sep="")) 
} 
dates

Lubridate es un paquete específico de de R que simplifica la labor de trabajar con fechas y horas en R.

Por ejemplo, si tratamos de recuperar la edad de una persona encuestada que no existe, obtendríamos un NULL, pues no hay ningún dato que corresponda con ello. En cambio, si tratamos de recuperar su estado civil, y la persona encuestada no contestó esta pregunta, obtendríamos un NA. NA también suele aparecer como resultado de una operación realizada, pero que no tuvo éxito por algún tipo de problema.

3 Verificación del tipo de dato

Al importar en ocasiones un fichero con datos, puede ocurrir que no sepamos cómo R ha los ha interpretado. Esto puede suponer un problema, puesto que determinadas operaciones sólo son posibles sobre un determinado tipo de datos; en caso de no ser posible, se obtienen mensajes de error. La función class() determina el tipo de un dato, incluyendo como argumento un dato o vector y devolviendo el tipo al que pertenece. Por ejemplo, para verificar qué tipo de datos que son 3, “3” y TRUE.

class(3)
class("3")
class(TRUE)

También podemos confirmar si un dato en cuestión pertenece a una tipología determinada con la familia de funciones is().

Función Tipo que verifican
is.integer() Entero
is.numeric() Numerico
is.character() Cadena de texto
is.factor() Factor
is.logical() Lógico
is.na() NA
is.null() NULL

Estas funciones toman como argumento un dato, devolviendo TRUE en caso de acertar el tipo de dato o FALSE en caso contrario. Por ejemplo, verificamos que 5 es un dato numérico.

is.numeric(5)

Si queremos verficar si 5 es de tipo cadena de texto.

is.character(5)

4 Coerción

Los datos originales pueden ser forzados a convertirse en otro tipo de datos. Este tipo de procedimiento es importante, ya que cuando R ejecuta una operación, intentará transformar (de manera implícita, sin avisarnos) los datos de su tipo original al tipo correcto para realizar dicha operación. En ocasiones, R tiene éxito y la instrucción se cumple sin problemas, pero en otras fallará y obtendremos un error.

Pero no todos los tipos de datos pueden ser transformados a todos los demás. De hecho, se sigue como regla general el siguiente orden, que va de los tipos de datos más restrictivos a los más flexibles:

lógico -> entero -> numérico -> cadena de texto (logical -> integer -> numeric -> character)

Las transformaciones no pueden ocurrir en orden inverso. Podemos cambiar un dato entero a uno numérico, pero no una cadena de texto a numérico. Como los datos de tipo lógico sólo admiten dos valores (TRUE y FALSE), estos son los más restrictivos; mientras que las cadenas de texto, al admitir cualquier combinación de caracteres, son los más flexibles.

Los factores son un caso particular. Al convertirse en valores numéricos con etiquetas asociadas, pueden ser transformados en valores numéricos o en cadenas de texto, pero en ambos casos se pierden sus niveles. También los datos numéricos y cadenas de texto pueden ser transformados en factor

Las transformaciones explícitas se realizan con la familia de funciones as().

Función Tipo al que hace coerción
as.integer() Entero
as.numeric() Numerico
as.character() Cadena de texto
as.factor() Factor
as.logical() Lógico
as.null() NULL

Todas estas funciones aceptan como argumento datos o vectores. Cuando la transformación ha tenido éxito, devuelven los datos del tipo pedido; si fallan, obtenemos NA como resultado. Por ejemplo, para convertir el número 5 a una cadena de texto. Para ello usamos la función as.character().

as.character(5)

Esta es una coerción válida. Pero, si intentamos convertir la palabra “cinco” a un dato numérico, obtendremos una advertencia y NA.

as.numeric("cinco")

Comprobemos el comportamiento especial de los factores. Podemos coercionar al número 5 y la palabra “cinco” en un factor.

as.factor(5)

as.factor("cinco")

Asignamos la palabra “cinco” como factor al objeto factor_cinco.

factor_cinco <- as.factor("cinco")
factor_cinco

Ahora podemos transformar factor_cinco a cadena de texto y a numérico.

as.character(factor_cinco)          # Cadena de texto
as.numeric(factor_cinco)            # Numérico

Si coercionamos un dato de tipo lógico a numérico, TRUE siempre devolverá 1 y FALSE dará como resultado 0.

as.numeric(TRUE)
as.numeric(FALSE)

Por último, la funcón as.null() siempre devuelve NULL, sin importar el tipo de dato que demos como argumento.

as.null(FALSE)                                                                  # Lógico
as.null(457)                                                                    # Numérico
as.null("palabra")                                                              # Cadena de texto

Desafío

  • Escribe el siguiente objeto: a <- c(1,2,3).

  • Pregunta si el objeto a es numérico.

  • Transforma los datos numéricos en caracteres.

  • Pregunta ahora si ahora sigue siendo numérico.

  • ¿Qué es entonces a a?

Cuando queramos limpiar de objetos la memoria (y la pantalla “environment”) podemos recurrir a la siguiente función:

rm(list = ls())                   # Elimina todos los objetos del área de trabajo