Vectores en R
En R, un vector atómico es la estructura de datos más fundamental. Se define como una secuencia ordenada de elementos que deben ser todos del mismo tipo de dato básico (atómico). Esto significa que un vector no puede mezclar, por ejemplo, números y texto directamente; si se intenta, R realizará una coerción para convertir todos los elementos al tipo más general (usualmente a carácter).
Los seis tipos atómicos básicos en R, de los cuales los primeros cuatro son los más usados en análisis de datos, son:
logical
: Contiene valores booleanos (TRUE
,FALSE
) y tambiénNA
(Not Available - dato perdido).integer
: Representa números enteros (ej.1L
,100L
,-5L
). Se debe usar el sufijoL
para asegurar que R lo trate como entero; de lo contrario, podría interpretarlo comodouble
.double
: (A menudo llamadonumeric
de forma genérica) Representa números reales o de punto flotante, es decir, números que pueden tener decimales (ej.2.5
,-3.14
,10.0
, o incluso10
si no se especificaL
).character
: Almacena cadenas de texto (ej."hola"
,'R es genial'
,"ID_001"
).complex
: Para números complejos (ej.1+2i
).raw
: Almacena bytes crudos (menos común en análisis de datos general).
Los vectores lógicos son especialmente importantes en R. Se utilizan comúnmente
como resultado de comparaciones (ej. edad > 30
, nombre == "Ana"
) y son
fundamentales para la subselección de datos (subsetting/filtering) en vectores,
matrices y data frames. Por ejemplo, mi_vector[mi_vector > 10]
seleccionará solo los
elementos mayores a 10. También controlan el flujo en estructuras como if
y
while
.
Para una exploración más profunda de los vectores y sus propiedades, consulta el capítulo sobre Vectores Atómicos y Listas en "Advanced R" de Hadley Wickham.
Creación de Vectores con c()
:
La función c()
(combinar o concatenar)
es la forma más común de crear vectores atómicos:
Vector Numérico
(double
):
Vector de Caracteres
(character
):
Vector Lógico
(logical
):
Operaciones Vectorizadas:
Una gran ventaja de R es que las operaciones aritméticas y lógicas se aplican elemento a elemento en los vectores, lo que se conoce como "vectorización". Esto hace que el código sea más conciso y eficiente.
Ejemplo: Sumar 5 a cada elemento del vector numérico creado anteriormente.
*Nota: Primero debes hacer clic en 'Crear Vector Numérico' para habilitar esta operación.
Usos Comunes de los Vectores:
- Almacenar series de datos (ej. mediciones de un experimento, temperaturas diarias, nombres de clientes).
- Como columnas individuales dentro de un data frame.
- Realizar cálculos matemáticos y estadísticos de forma eficiente (sumas, promedios, etc.).
- Para la indexación y subselección de elementos en otras estructuras de datos.
- Argumentos para funciones que esperan múltiples valores del mismo tipo.
Data Frames en R
Un Data Frame es la estructura de datos más utilizada para el análisis de datos tabulares en R. Es esencialmente una lista de vectores de igual longitud, donde cada vector representa una columna.
Los data frames son el análogo en R a una tabla de una base de datos SQL o una hoja de cálculo. Para más detalles sobre su estructura y manipulación, puedes consultar el capítulo sobre Tibbles (una versión moderna de data frames) en "Advanced R".
- Cada columna es un vector y, por lo tanto, homogénea en tipo.
- Diferentes columnas pueden tener diferentes tipos de datos (heterogeneidad entre columnas).
- Todas las columnas deben tener la misma longitud (mismo número de filas).
- Poseen nombres de columna y, opcionalmente, nombres de fila.
Construcción de un Data Frame a partir de Vectores (Personas y Salarios):
Imagina que tenemos los siguientes vectores que representan información sobre personas:
Nombres (Carácter):
Edades (Numérico):
Salarios (Numérico):
Usamos la función data.frame()
para
combinarlos en una estructura tabular:
1. Matriz (Matrix)
Colección bidimensional de elementos del MISMO tipo.
Col1 | Col2 |
---|
Todos los elementos deben ser del mismo tipo (ej. numérico).
Características Clave:
- Bidimensional (filas y columnas).
- Homogénea: todos los elementos son del mismo tipo. Si se mezclan, R realiza coerción al tipo más general.
- Eficiente para operaciones de álgebra lineal.
Cuándo Usarla:
- Cálculos matemáticos (ej. multiplicación de matrices).
- Datos tabulares homogéneos (ej. matriz de correlaciones, pixeles de imagen en escala de grises).
- Representación de grids o mapas de calor.
Potencialidad:
- Alta eficiencia en operaciones numéricas vectorizadas.
- Base para muchos algoritmos estadísticos y de machine learning.
Ejemplo en R:
# Matriz numérica mi_matriz <- matrix(1:6, nrow = 3, ncol = 2) print(mi_matriz) # [,1] [,2] # [1,] 1 4 # [2,] 2 5 # [3,] 3 6 # Coerción: si intentas mezclar tipos matriz_forzada <- matrix(c("a", 1, "b", 2), nrow = 2) print(matriz_forzada) # Todos se convierten a caracteres # [,1] [,2] # [1,] "a" "b" # [2,] "1" "2"
2. Array (Arreglo)
Generalización de una matriz (multidimensional). Todos los elementos del MISMO tipo.
Array 3D (2 capas, 2 filas, 2 columnas)
Imagina "pilas" de matrices, todas con el mismo tipo de dato.
Características Clave:
- Multidimensional (puede tener 1, 2, 3, o más dimensiones).
- Homogénea: todos los elementos deben ser del mismo tipo.
- Un vector es un array de 1D, una matriz es un array de 2D.
Cuándo Usarlo:
- Datos inherentemente multidimensionales y homogéneos.
- Imágenes a color (ej., alto x ancho x 3 canales RGB).
- Datos de series temporales de múltiples variables observadas en múltiples ubicaciones.
- Resultados de simulaciones donde se varían múltiples parámetros.
- Tensores en machine learning.
Potencialidad:
- Permite representar estructuras de datos complejas de forma natural.
- Las operaciones se pueden aplicar a través de las dimensiones ("slicing", "dicing").
- Útil en campos como el procesamiento de imágenes, física, y ciertos tipos de análisis estadísticos avanzados.
Ejemplo en R (General):
# Array de 3 dimensiones (2 filas, 2 columnas, 2 "láminas") # Todos los elementos serán numéricos mi_array <- array(1:8, dim = c(2, 2, 2)) print(mi_array) # , , 1 (Primera lámina) # [,1] [,2] # [1,] 1 3 # [2,] 2 4 # , , 2 (Segunda lámina) # [,1] [,2] # [1,] 5 7 # [2,] 6 8
Caso de Uso Aplicado: Mini Imagen RGB
Un array de 3 dimensiones es ideal para representar una imagen a color. Por ejemplo, una imagen de 2x2 píxeles con canales Rojo, Verde y Azul (RGB):
- Dimensión 1: Alto de la imagen (número de filas de píxeles).
- Dimensión 2: Ancho de la imagen (número de columnas de píxeles).
- Dimensión 3: Canales de color (R, G, B), usualmente 3 capas.
# Suponiendo una imagen muy pequeña de 2x2 píxeles # Los valores podrían ir de 0 a 255 para cada canal de color # Datos para los canales R, G, B (simplificado) # Capa 1: Canal Rojo # Píxel (1,1)=255, Píxel (1,2)=0 # Píxel (2,1)=0, Píxel (2,2)=128 # Capa 2: Canal Verde # Píxel (1,1)=0, Píxel (1,2)=255 # Píxel (2,1)=128, Píxel (2,2)=0 # Capa 3: Canal Azul # Píxel (1,1)=0, Píxel (1,2)=0 # Píxel (2,1)=255, Píxel (2,2)=128 imagen_rgb <- array( c(255,0,0,128, # Canal Rojo (columna por columna) 0,255,128,0, # Canal Verde 0,0,255,128), # Canal Azul dim = c(2, 2, 3), # 2 filas, 2 columnas, 3 capas de color dimnames = list( c("Fila1", "Fila2"), c("Col1", "Col2"), c("Rojo", "Verde", "Azul") ) ) print(imagen_rgb) # , , Rojo # Col1 Col2 # Fila1 255 0 # Fila2 0 128 # # , , Verde # Col1 Col2 # Fila1 0 255 # Fila2 128 0 # # , , Azul # Col1 Col2 # Fila1 0 0 # Fila2 255 128 # Acceder al valor del canal Verde del píxel en Fila1, Col2: valor_verde_pixel_1_2 <- imagen_rgb["Fila1", "Col2", "Verde"] print(valor_verde_pixel_1_2) # Debería ser 255
Esta estructura es fundamental en el procesamiento de imágenes y visión por computadora.
3. Tibbles (del paquete tibble
)
Los Tibbles son una reimaginación moderna de los data frames en R, parte del Tidyverse. Mantienen la estructura fundamental de los data frames pero con algunas mejoras y comportamientos más predecibles.
Puedes aprender mucho más sobre ellos en el capítulo de Tibbles en "R for Data Science".
Ventajas Clave sobre Data Frames Base:
- Mejor Impresión (
print
): Solo muestran las primeras 10 filas y las columnas que caben en pantalla, junto con el tipo de cada columna. Esto evita inundar la consola con datos grandes. - No convierten strings a factores: Por defecto, las cadenas de caracteres se
mantienen como
character
, no se convierten automáticamente afactor
(stringsAsFactors = FALSE
es el comportamiento implícito y no configurable). - No usan nombres de fila (
rownames
): Fomentan el almacenamiento de identificadores como una columna explícita en los datos. - Subsetting más consistente:
[
siempre devuelve otro tibble, incluso si se selecciona una sola columna. Para extraer un vector, se usa[[
o$
. - Evaluación perezosa de argumentos: Los argumentos de
tibble()
se evalúan secuencialmente, permitiendo referenciar columnas recién creadas en la misma llamada.
Ejemplo de Creación y Salida en R:
# Primero, necesitarías instalar y cargar el paquete: # install.packages("tibble") # Solo una vez # library(tibble) # Creando un tibble mi_tibble <- tibble( Nombre = c("Carlos", "Laura", "Pedro", "Sofia", "Ana", "Juan", "Maria", "Luis", "Elena", "David", "Isabel"), Puntaje = c(85, 92, 78, 95, 88, 72, 90, 81, 93, 76, 89), Activo = c(TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE) ) print(mi_tibble) # # A tibble: 11 × 3 # Nombre Puntaje Activo # <chr> <dbl> <lgl> # 1 Carlos 85 TRUE # 2 Laura 92 FALSE # 3 Pedro 78 TRUE # 4 Sofia 95 TRUE # 5 Ana 88 FALSE # 6 Juan 72 TRUE # 7 Maria 90 TRUE # 8 Luis 81 FALSE # 9 Elena 93 TRUE # 10 David 76 FALSE # # ℹ 1 more row # # ℹ Use `print(n = ...)` to see more rows
Nota cómo la salida del tibble es más informativa y compacta que la de un data frame base, especialmente con más filas.
Tipos de Datos Numéricos en R
Comprender la diferencia entre integer
,
numeric
y double
es clave para el manejo eficiente de datos y la precisión
en R.
1. integer
(Entero)
Representa números enteros (sin parte decimal, ej: -3, 0, 5, 100).
- Ocupan menos memoria que los números
numeric
de punto flotante. - Para asegurar que un número se trate como
integer
, se añade el sufijoL
.
# Ejemplo de Integer x <- 10L print(x) # Muestra: 10 class(x) # Devuelve: "integer" typeof(x) # Devuelve: "integer" (cómo R lo almacena internamente) is.integer(x) # Devuelve: TRUE is.numeric(x) # Devuelve: TRUE (porque un integer es un tipo de numeric) # Si no usas L, R por defecto lo trata como 'numeric' (double) incluso si es un entero: y <- 10 class(y) # Devuelve: "numeric" typeof(y) # Devuelve: "double" is.integer(y) # Devuelve: FALSE
2. numeric
/ double
(Numérico / Doble Precisión)
Representa números reales, que pueden tener una
parte decimal (ej: -2.5, 0.0, 3.14159). En R, el tipo numeric
es, por defecto, de
"doble precisión" (double
).
double
es el término técnico más preciso para cómo R almacena los números de punto flotante. "Doble precisión" significa que se utilizan más bits (generalmente 64 bits) para almacenar el número, lo que permite un rango más amplio de valores y mayor precisión para los decimales.numeric
es el nombre de la clase que R le da a estos números.- Es el tipo de dato numérico más común y general en R.
# Ejemplo de Numeric/Double a <- 3.14159 print(a) # Muestra: 3.14159 class(a) # Devuelve: "numeric" typeof(a) # Devuelve: "double" is.double(a) # Devuelve: TRUE (o is.numeric(a)) b <- 100.0 # También es numeric (double) class(b) # Devuelve: "numeric" typeof(b) # Devuelve: "double"
Cuándo Usar Cada Uno:
Tipo | Descripción | Cuándo Usar | Sufijo en R | typeof() |
---|---|---|---|---|
integer |
Números enteros exactos. | Conteos, índices, IDs, cuando la memoria es crítica y los datos son estrictamente enteros sin decimales. | L (ej. 5L ,
-2L )
|
"integer" |
numeric (double ) |
Números reales, con o sin decimales. Mayor precisión y rango. | Por defecto para cualquier número. Cálculos científicos, mediciones, datos financieros, la mayoría de las situaciones. | Ninguno (ej. 5 ,
3.14 )
|
"double" |
Nota Importante: La función class()
te dice cómo R ve el objeto en
términos de su sistema de objetos (orientado a objetos). typeof()
te da una
indicación más cercana al tipo de almacenamiento fundamental del objeto en la memoria. Para la
mayoría de los propósitos prácticos, la distinción entre numeric
y
double
no es crítica, ya que R maneja las conversiones de manera transparente. Sin
embargo, integer
sí tiene implicaciones de almacenamiento y precisión.
Factor vs. Character en R
Ambos se usan para datos textuales, pero tienen diferencias fundamentales, especialmente para el análisis estadístico.
1. character
(Cadena de Caracteres)
Almacena secuencias de texto tal cual. Es el tipo de dato más directo para texto.
- Flexibilidad: Puede contener cualquier texto.
- Almacenamiento: Guarda cada cadena de forma individual.
- Uso común: Nombres propios, respuestas a preguntas abiertas en encuestas, IDs textuales únicos, cualquier texto que no represente una categoría fija.
# Vector de caracteres: Opiniones sobre un servicio opiniones_servicio <- c("Bueno", "Excelente", "Bueno", "Regular") print(opiniones_servicio) # [1] "Bueno" "Excelente" "Bueno" "Regular" class(opiniones_servicio) # [1] "character"
2. factor
(Factor)
Diseñado para representar datos categóricos con un número limitado y conocido de categorías o "niveles" (levels).
- Categorías Fijas: Los factores tienen un conjunto predefinido de niveles. Ideal para variables como "género", "grupo de tratamiento", "nivel educativo".
- Almacenamiento Eficiente: Internamente, R almacena los factores como enteros (índices de sus niveles), lo que puede ser más eficiente en memoria si hay muchas repeticiones de pocas categorías.
- Importancia en Modelado: Muchos modelos estadísticos en R (ej.
lm()
,glm()
, ANOVA) tratan los factores de manera especial para crear variables dummy o contrastes adecuados. - Orden: Los factores pueden ser ordenados (ordinales, ej. "Bajo" < "Medio" < "Alto" ) o no ordenados (nominales).
# Crear un factor para niveles de satisfacción satisfaccion <- c("Satisfecho", "Neutral", "Insatisfecho", "Satisfecho") factor_satisfaccion <- factor(satisfaccion) print(factor_satisfaccion) # [1] Satisfecho Neutral Insatisfecho Satisfecho # Levels: Insatisfecho Neutral Satisfecho (orden alfabético por defecto) class(factor_satisfaccion) # [1] "factor" levels(factor_satisfaccion) # Muestra los niveles únicos # [1] "Insatisfecho" "Neutral" "Satisfecho" as.integer(factor_satisfaccion) # Muestra cómo se almacenan internamente # [1] 3 2 1 3 (según el orden de los niveles) # Factor ordenado (ordinal) niveles_educativos <- c("Primaria", "Secundaria", "Universidad", "Secundaria") factor_educ_ord <- factor(niveles_educativos, levels = c("Primaria", "Secundaria", "Universidad"), ordered = TRUE) print(factor_educ_ord) # [1] Primaria Secundaria Universidad Secundaria # Levels: Primaria < Secundaria < Universidad factor_educ_ord[1] < factor_educ_ord[3] # Comprobación de orden # [1] TRUE
Diferencias Clave y Cuándo Usar Cada Uno
Característica | character |
factor |
---|---|---|
Propósito Principal | Almacenar texto genérico. | Representar variables categóricas con niveles definidos. |
Niveles (Levels) | No tiene concepto de "niveles" predefinidos. | Tiene un conjunto fijo de niveles. Los valores deben pertenecer a estos niveles. |
Almacenamiento Interno | Como cadenas de texto. | Como enteros que mapean a los niveles (más eficiente para datos categóricos repetitivos). |
Modelado Estadístico | Puede necesitar conversión explícita o ser tratado como texto simple. | Tratado automáticamente como variable categórica, generando variables dummy/contrastes. |
Orden | Sin orden inherente (solo alfabético si se ordena). | Puede ser nominal (sin orden) u ordinal (con orden definido, ej. "Bajo", "Medio", "Alto"). |
Añadir Nuevos Valores | Fácil, se añade la nueva cadena. | Si un nuevo valor no está en los niveles
definidos, se convierte en <NA> (dato perdido) a menos que se añada
explícitamente el nivel. |
Cuándo Usar | IDs únicos, texto libre, descripciones, cuando no hay categorías fijas o el orden no importa para el análisis. | Variables categóricas (género, grupos de tratamiento, tallas), variables ordinales (nivel de satisfacción, nivel educativo), cuando se usarán en modelos estadísticos que requieren variables categóricas. |
Importante: En R >= 4.0.0, el comportamiento por defecto de funciones como
data.frame()
es stringsAsFactors = FALSE
, manteniendo los caracteres como
tal. Esto es generalmente preferido para evitar conversiones automáticas no deseadas a factor. Se
recomienda convertir explícitamente a factor cuando sea necesario. Para más información sobre
factores, visita el capítulo de Factors en "R for Data
Science" o el de Factors en "Advanced R".
Visualización Dinámica: Creación de un Factor
Paso 1: Vector de Caracteres Original (Niveles de Satisfacción)
Paso 2: Convertir a Factor y Ver Niveles
Al convertir a factor con factor()
, R
identifica los valores únicos como "niveles". Con levels()
podemos verlos.
Paso 3: ¿Qué pasa al añadir un nuevo valor no existente en los niveles?
Intentemos añadir "Muy Satisfecho" (un valor que no es un nivel actual) al vector y al factor:
Nuevo Vector Character:
Nuevo Vector Factor (¡Ojo!):