Los tipos de datos de R
Cada valor en R tiene uno de un pequeño conjunto de tipos atómicos. Cuatro de ellos hacen casi todo el trabajo:
- double - números decimales:
3.14,-2,1e6. Esto es lo que R quiere decir con "numeric", y es el tipo por defecto de cualquier número que escribas. - integer - números enteros almacenados de forma exacta, escritos con un sufijo
L:42L. - character - texto entre comillas:
"hello". - logical - los dos valores de verdad
TRUEyFALSE(másNA, el valor ausente - mira valores ausentes).
También existe complex (2 + 3i) para el ocasional cálculo de procesamiento de señales; puedes pasar años sin necesitarlo. typeof() te dice qué tipo tiene un valor:
Fíjate en la primera línea: un número a secas es un double aunque parezca entero. typeof(42) es "double"; solo 42L es un integer. En el análisis del día a día la diferencia rara vez importa - R convierte entre ellos en silencio - pero explica mucha de la salida de typeof() que de otro modo resultaría confusa.
typeof() vs class(): por qué discrepan
R tiene dos funciones que parecen responder ambas a "¿qué es esto?", y responden a preguntas sutilmente distintas.
typeof()informa del tipo de almacenamiento: cómo se guarda el valor en memoria.class()informa del tipo de comportamiento: la etiqueta que usa el despacho de métodos de R para decidir, por ejemplo, quéprintosummaryejecutar.
Para valores simples las respuestas difieren solo en vocabulario:
typeof() dice double (el almacenamiento), class() dice numeric (el comportamiento). Para las estructuras, la brecha se ensancha:
La matriz se almacena como un vector de enteros a secas, pero se comporta como una matriz - class() es lo que le dice a R que la imprima como una cuadrícula. La misma división aparece con los data frames (typeof dice "list", class dice "data.frame") y las fechas (typeof dice "double", class dice "Date").
La regla práctica: usa class() cuando quieras saber qué es algo en el sentido cotidiano, y typeof() cuando estés depurando lo que R hace bajo el capó.
Comprobar tipos con is.*()
Cada tipo tiene un predicado correspondiente que devuelve TRUE o FALSE - práctico dentro de funciones que necesitan validar su entrada:
Una trampa que vale la pena conocer: is.numeric() es TRUE tanto para doubles como para integers (ambos son números), pero is.integer() comprueba el almacenamiento, así que es FALSE para un 42 a secas:
Si alguna vez te ha sorprendido que is.integer(7) sea FALSE para un número que obviamente es entero en el sentido matemático - esta es la razón. 7 es un double; 7L es un integer.
Convertir tipos con as.*()
La conversión explícita usa la familia as.*, una función por tipo de destino:
Dos comportamientos a recordar. as.integer() trunca hacia cero en lugar de redondear - 7.9 se convierte en 7. Y cuando una conversión no tiene sentido, R no lanza un error; devuelve NA y emite una advertencia:
Ejecuta eso y verás NA más una advertencia "NAs introduced by coercion". Esto es genuinamente útil - convierte una columna entera de texto desordenado a números y las entradas imposibles de parsear se convierten en NA en lugar de tumbar tu script - pero también significa que un NA silencioso puede colarse en tus datos. Cuando una conversión importa, comprueba si hay nuevos NA después.
Los lógicos se convierten hacia y desde números como cabría esperar: as.numeric(TRUE) es 1, as.logical(0) es FALSE. Por eso sum() de un vector lógico cuenta los TRUE:
Coerción implícita: la regla de un solo tipo para los vectores
Un vector atómico en R solo puede contener un tipo. Combina valores mezclados con c() y R promociona silenciosamente todo al tipo más flexible presente, siguiendo una escalera fija:
logical → integer → double → character
Los lógicos se convirtieron en 1 y 0, los enteros en doubles, y en la última línea todo se convirtió en texto - character siempre gana, porque cualquier valor puede escribirse como cadena. Puedes confirmarlo con typeof():
La coerción es la fuente número uno de los bugs de "¿por qué mi columna es texto?": una cadena "N/A" perdida en una columna de números coerciona el vector entero a character. Cuando eso ocurra, arregla primero el valor problemático y luego convierte de vuelta con as.numeric().
Lo que te llevas
- Cuatro tipos de carga: double ("numeric"), integer (
42L), character, logical. typeof()= cómo se almacena;class()= cómo se comporta.3.14es undoubleque se comporta comonumeric.- Comprueba con
is.numeric()y compañía; convierte conas.numeric()y compañía - las conversiones fallidas danNAcon una advertencia, no un error. - Los vectores contienen un solo tipo; mezclar coerciona siguiendo logical → integer → double → character.
Lo siguiente: una mirada más de cerca a los tipos numéricos - redondeo, funciones matemáticas y las sorpresas de coma flotante que comparten todos los lenguajes.
Preguntas frecuentes
¿Cuáles son los tipos de datos básicos en R?
Los tipos atómicos son double (números decimales, lo que R llama "numeric"), integer (números enteros escritos con un sufijo L, como 42L), character (texto entre comillas), logical (TRUE/FALSE) y el rara vez usado complex. Todo lo más grande - vectores, data frames, listas - se construye a partir de estos.
¿Cuál es la diferencia entre typeof() y class() en R?
typeof() informa de cómo se almacena un valor en memoria (su tipo de bajo nivel); class() informa de cómo se comporta el valor, que es lo que controla qué métodos despacha R. Para un decimal simple discrepan en la palabra - typeof(3.14) es "double" mientras que class(3.14) es "numeric" - y para estructuras como los data frames typeof() dice "list" mientras que class() dice "data.frame".
¿Cómo se convierten tipos en R?
Usa la familia as.*: as.numeric("3.5") da 3.5, as.character(42) da "42", as.integer(7.9) trunca a 7. Cuando una conversión es imposible, R devuelve NA y lanza una advertencia en lugar de un error - as.numeric("abc") es NA.
¿Qué es la coerción en R?
Cuando combinas tipos distintos en un vector, R convierte silenciosamente todo al tipo más flexible, siguiendo el orden logical → integer → double → character. Así, c(1, 2, "three") se convierte en un vector de caracteres: "1" "2" "three".