https://eduard-martinez.github.io
📊 Este capítulo es el punto de partida para adentrarse en el mundo de R, un lenguaje de programación para el análisis de datos, la estadística y la ciencia de datos. El estudiante descubrirá qué es R y cómo usar RStudio; el entorno de trabajo donde aprenderá a programar, para transformar datos en insumos para la toma de decisiones, responder preguntas de investigación y crear visualizaciones que comuniquen sus hallazgos.
💻 Exploraremos los tipos de datos básicos (numéricos, texto, lógicos y valores especiales), cómo se manejan objetos en R y cómo trabajar con vectores, matrices, dataframes y listas. También aprenderás qué es el Workspace, el papel de las librerías y funciones, y cómo interpretar los resultados de la consola.
🧰 Piense en este capítulo como su kit de herramientas inicial: lo que aprendra aquí será la base para todo lo que desarrolle más adelante.
R es el lenguaje de programación y el motor de cálculo; RStudio es la interfaz gráfica que facilita trabajar con ese motor.
R (motor de cálculo)
RStudio (IDE)
La consola constituye el espacio donde se introducen instrucciones y
se observa de inmediato el resultado de la evaluación. Cada línea
comienza con el símbolo de promp >; al pulsar
Enter se ejecuta la instrucción y, debajo, se imprime el valor
devuelto o un mensaje de advertencia o error según corresponda. En la
parte superior se visualiza el historial de comandos, lo que permite
reutilizar expresiones previas mediante las flechas del teclado o la
función history().
Cuando el código es más extenso o se desea conservarlo para futuras ejecuciones, lo ideal es trabajar en el Script. Este es un archivo de texto donde se escriben, organizan y comentan las instrucciones antes de ejecutarlas, permitiendo correr una sola línea, un bloque o el programa completo.
RStudio abre, por defecto, una ventana dividida en cuatro paneles principales, cada uno asociado a una fase del flujo de trabajo:
Ctrl + Enter; el script completo se ejecuta con
Ctrl + Shift + S o mediante el botón
Source.Warning), mensajes
(Message) y errores (Error).history().?función) y viñetas (vignette()).Antes de crear objetos, conviene repasar las operaciones básicas y la forma de visualizar resultados en la consola. R permite realizar cálculos aritméticos, evaluaciones lógicas y comparaciones con una sintaxis simple y reglas de precedencia estándar. En esta sección se presentan estos operadores y ejemplos mínimos para interpretar correctamente la salida.
Se utilizan los operadores aritméticos estándar para sumar, restar, multiplicar, dividir y elevar potencias.
| Operador | Descripción | Ejemplo |
|---|---|---|
+
|
Suma | 3 + 2 |
-
|
Resta | 7 - 4 |
*
|
Multiplicación | 6 * 3 |
/
|
División | 8 / 2 |
^, **
|
Exponenciación | 2^3 |
%%
|
Módulo (resto de división) | 10 %% 3 |
%/%
|
División entera | 10 %/% 3 |
Ejemplo de operaciones aritméticas:
1 + 2 # Suma
[1] 3
5 / 2 # División
[1] 2.5
100 %/% 60 # ¿Cuántas horas enteras hay en 100 minutos?
[1] 1
100 %% 60 # ¿Cuántos minutos quedan?
[1] 40
Por defecto, R evalúa siguiendo estas reglas de precedencia (de mayor a menor):
1. ^ → 2) * y / → 3) + y -.
Cuando se desea alterar este orden, conviene usar paréntesis para
hacer explícita la intención y evitar ambigüedades. En expresiones
largas, es buena práctica comentar el resultado esperado al final de la
línea.+y-` (suma y resta)
3 + 2 * 4 # Multiplicación antes de la suma (resultado: 11)
[1] 11
(3 + 2) * 4 # Uso de paréntesis para cambiar precedencia (resultado: 20)
[1] 20
R incluye operadores lógicos elemento a elemento. Úsalos para filtrar, combinar condiciones y construir expresiones.
| Operador | Descripción | Ejemplo |
|---|---|---|
| < , > | Menor y mayor que | 5 > 3 |
| <= , >= | Menor o igual y mayor igual que | 5 >= 5 |
==
|
Igual a | 3 == 3 |
!=
|
Diferente de | 3 != 4 |
&
|
y (AND lógico) | TRUE & FALSE |
|
|
o (OR lógico) | TRUE | FALSE |
!
|
Negación lógica | !TRUE |
Ejemplos de operadores lógicos:
1 > 2 # ¿Es 1 mayor que 2?
[1] FALSE
1 > 2 & 1 > 0.5 # ¿Es 1 mayor que 2 y mayor que 0.5?
[1] FALSE
1 > 2 | 1 > 0.5 # ¿Es 1 mayor que 2 o mayor que 0.5?
[1] TRUE
isTRUE(1 < 2) # TRUE (solo TRUE exacto; NA o 1 no pasan)
[1] TRUE
3 != 4 # TRUE (son diferentes)
[1] TRUE
c(TRUE, FALSE) & c(TRUE, TRUE) # Devuelve TRUE si ambos valores en la misma posición son TRUE
[1] TRUE FALSE
Precaución con la precedencia: Los operadores
relacionales (>, <, ==) se
evalúan antes que (&, |) ya que tiene
precedencia alta.
1 > 0.5 & 2 # ¿Qué pasa aquí?
[1] TRUE
Para evitar confusión, siempre compare valores explícitamente:
1 > 0.5 & 1 > 2 # Evaluación correcta
[1] FALSE
%in%%in% verifica si cada elemento del lado izquierdo
pertenece al conjunto del lado derecho. Es vectorizado y la forma
preferida para “está en…”.
4 %in% 1:10 # ¿Está 4 en la secuencia del 1 al 10?
[1] TRUE
4 %in% 5:10 # ¿Está 4 en la secuencia del 5 al 10?
[1] FALSE
c(4, 11) %in% 1:10
[1] TRUE FALSE
También podemos evaluar igualdad con ==. Sin embargo,
== compara posición a posición y puede reciclar vectores
(riesgo de errores). Para “pertenece a uno de varios valores”, usa
%in%.
1:6 == 4 # compara contra un escalar -> c(FALSE,FALSE,FALSE,TRUE,FALSE,FALSE)
[1] FALSE FALSE FALSE TRUE FALSE FALSE
1:6 == c(4,5) # recicla: compara por posición (cuidado)
[1] FALSE FALSE FALSE FALSE FALSE FALSE
1:6 %in% c(4,5) # forma correcta para pertenencia múltiple
[1] FALSE FALSE FALSE TRUE TRUE FALSE
En R se trabaja con valores que pertenecen a categorías básicas. Por ahora se usaran tres grandes grupos: numéricos, texto y lógicos. Además, verás algunos valores especiales que aparecen en cálculos.
Incluyen enteros y números reales (decimales). Se pueden escribir en notación usual o científica.
10 # entero (R lo maneja como numérico)
[1] 10
3.14 # decimal
[1] 3.14
1e6 # notación científica: 1 * 10^6
[1] 1e+06
Las cadenas se escriben entre comillas simples o dobles. Ambas
funcionan igual; solo asegúrate de abrir y cerrar con el mismo tipo.
Para incluir comillas dentro de una cadena, escápalas con . Las cadenas
admiten secuencias de escape útiles como (salto de línea) y tabulación).
R maneja bien acentos y eñes si tu archivo está en
UTF-8.
"Hola mundo"
[1] "Hola mundo"
"Comillas \"dentro\" de comillas"
[1] "Comillas \"dentro\" de comillas"
'Líneas:\nPrimera\nSegunda' # '\n' se interpreta como salto de línea
[1] "Líneas:\nPrimera\nSegunda"
Los valores lógicos representan verdadero o falso y no llevan
comillas: se escriben TRUE y FALSE (en
mayúsculas). Evita T y F porque son nombres de
objetos y podrían estar redefinidos. El operador ! niega,
& es AND y | es OR. Ten en cuenta que
& y | operan elemento a elemento, mientras
que && y || evalúan solo el primer
elemento (algo útil cuando trabajes con condiciones escalares).
TRUE
FALSE
!TRUE # negación
TRUE & FALSE # AND
TRUE | FALSE # OR
Dato útil: en operaciones aritméticas,
TRUE se comporta como 1 y FALSE como
0. (Esto permite contar condiciones más adelante, sin
introducir funciones por ahora.)
Al calcular en R pueden aparecer valores especiales que conviene
identificar: NA, que representa un dato faltante o
desconocido y puede darse en cualquier tipo; Inf y
-Inf, que indican infinitos (por ejemplo, al dividir por
cero con numerador no nulo); NaN, que señala un resultado
indeterminado o “no numérico” (como 0/0); y
NULL, que denota ausencia de valor u objeto y no es
equivalente a NA.
NA # dato faltante
Inf # infinito
-Inf # menos infinito
NaN # indeterminado
NULL # ausencia de valor
¿Cómo suelen aparecer?
1/0 # Inf
[1] Inf
-1/0 # -Inf
[1] -Inf
0/0 # NaN
[1] NaN
1 + NA # NA (cualquier operación con NA suele dar NA)
[1] NA
Diferencias clave: NA indica que hay un lugar para un
valor, pero no sabemos cuál es; NULL significa que no hay
valor (ausencia total); NaN corresponde a un resultado
indeterminado de una operación numérica; y
Inf/-Inf representan resultados no acotados
que crecen sin límite.
Cuando R está listo para ejecutar una instrucción, muestra el prompt
>. Si al presionar Enter la instrucción quedó incompleta
(p. ej., paréntesis o comillas sin cerrar, o un operador al final de la
línea), R cambia al prompt de continuación +, indicando que
espera que completes lo que falta. Ejemplos que provocan + (no se
ejecutan, solo ilustran):
> (1 + 2 # falta cerrar el paréntesis
+ "hola # falta cerrar la comilla
Para volver al > se debe completar lo pendiente y
presiona Enter o cancelar la entrada actual con
Esc (en RStudio.
Cada expresión evaluada puede producir uno de estos resultados:
1 + 2
[1] 3
2 + "2"
Error in 2 + "2": argumento no-numérico para operador binario
Resumen rápido:
• ">" listo para ejecutar; "+" esperando que completes una instrucción.
• Resultado: valor calculado.
• Message: información; no detiene.
• Warning: posible problema; no detiene.
• Error: detiene la ejecución.
• En Rmd: usa message=FALSE, warning=FALSE, error=TRUE con criterio.
Una librería (paquete) es un conjunto de funciones,
datos y documentación pensadas para resolver tareas específicas (p. ej.,
tidyverse para manipulación/visualización, rio
para importación/exportación).
install.packages()library() o require()update.packages()install.packages("tidyverse")
install.packages(c("skimr","rio"))
Nota: library("pkg") lanza error si al
llamar la librería no está instalada. require("pkg")
devuelve TRUE/FALSE; si no está, pero no
detiene el script.
library(tidyverse)
require(skimr)
Nota: puede inspeccionar las librerías que tiene
activas en su sesión corriendo la función sessionInfo()
sobre la consola de R. Cuando inicia sesión, R carga 7 librerías bases
(usted,stats,graphics,grDevices,utils,
datasets, methods y base). Pero
usted puede instalar/llamar cerca de 22147 librerías disponibles en el
CRAN de R.
sessionInfo()
Una función permite crear, editar, transformar o eliminar objetos. Están contenidas en librerías. Y cada función contiene por lo menos 1 argumento.
Nota: Toda función abre con ( y debe cerrar con un ). Aseguresé de ejecutar la función así, para que R entienda hasta que punto debe ejecutar esa funcíon.
En R, la documentación integrada es el primer recurso para entender
qué hace una función, qué argumentos
acepta y qué devuelve. Se recomienda consultar
la ayuda antes de probar “a ciegas”. Para obtener más
información sobre una función u objeto (con nombre) en R, consulte la
documentación de “help” o usando ?:
help(rnorm)
starting httpd help server ... done
?rnorm
Hint: ¿Ves la sección Ejemplos en la parte
inferior del archivo de ayuda? Puedes ejecutarlos con la función
example().
example(rnorm)
Las secciones más útiles son:
Para inspeccionar los argumentos de una función y sus valores por
defecto. args(rnorm) muestra los nombres y el orden de los
argumentos que la función espera; para rnorm se verá algo
como function (n, mean = 0, sd =1), lo que indica que n no
tiene valor por defecto (es obligatorio) y que mean y
sd por defecto son 0 y 1.
formals(rnorm) devuelve una lista con los argumentos
formales y sus valores por defecto; allí mean = 0 y
sd = 1, mientras que n aparece sin valor
(obligatorio). Esto ayuda a llamar funciones de forma segura (por nombre
o por posición) y a cambiar solo lo necesario.
args(rnorm) # nombres y orden de argumentos
function (n, mean = 0, sd = 1)
NULL
formals(rnorm) # valores por defecto
$n
$mean
[1] 0
$sd
[1] 1
Cuando se usa los argumentos por posición se depende estrictamente
del orden definido en la firma de la función (por ejemplo,
rnorm(n, mean = 0, sd = 1)), de modo que un intercambio
accidental puede generar una media o desviación equivocadas sin lanzar
error. Al usar argumentos con nombre (n =, mean =, sd =),
el código queda autoexplicativo, tolera el reordenamiento y resulta más
robusto cuando se añaden parámetros opcionales; como regla práctica,
suele recomendarse nombrar los argumentos no obvios y, si se desea,
dejar por posición únicamente los indispensables (p. ej., n).
rnorm(n = 5, mean = 10, sd = 2) # por nombre (más claro)
[1] 12.238345 6.296325 9.684968 7.512777 14.903888
rnorm(5, 10, 2) # por posición (equivalente)
[1] 13.152211 9.075725 7.873562 9.228694 6.888133
Para muchos paquetes, también puede probar la función
vignette(), que proporcionará una introducción a un paquete
y su propósito a través de una serie de ejemplos útiles. Una
complicación es que necesita saber el nombre exacto de la(s) viñeta(s)
del paquete. Intente ejecutar:
vignette("base")
Al igual que las viñetas, muchos paquetes vienen con demostraciones interactivas integradas. Para enumerar todas las demostraciones disponibles en su sistema:
demo("graphics", package = "graphics")
demo(package = .packages(all.available = TRUE))
En R todo se maneja como objetos a los que se les asigna
un nombre en el espacio de trabajo (environment). Un objeto puede ser
vector, matriz, data frame, lista o incluso una función, y su clase
determinan qué operaciones son válidas y cómo se comporta. La asignación
simplemente vincula un nombre con un valor (resultado de una expresión o
función). Luego, los objetos pueden inspeccionarse, indexarse,
convertirse entre formas compatibles (p. ej., de data frame a matriz) y
reutilizarse en nuevos cálculos. En análisis reproducible conviene usar
nombres claros y consistentes, y evitar palabras reservadas para no
interferir con el lenguaje.
Para asignar un objeto se debe seguir la siguiente estructura:
nombre_objeto + asignar + funcion()
# Una forma de hacerlo:
data_1 <- rnorm(n = 10 , mean = 50 , sd = 10)
# Otra forma de hacerlo:
data_2 = rnorm(n = 10 , mean = 40 , sd = 10)
¿Qué operador de asignación usar?
La mayoría de los usuarios de R (¿puristas?) parecen preferir
<- para la asignación, ya que = también
tiene un papel específico para la evaluación dentro de las
funciones.
Veremos muchos ejemplos de esto más adelante.
Pero no creo que importe; = es más rápido de
escribir y es más intuitivo si vienes de otro lenguaje de programación.
(Más discusión aquí)
Conclusión: Use el que prefiera. Solo sea consistente dentro de su propio código. i.e: Usa el mismo operador en la medida de lo posible.
También puede asignar objetos usando la siguiente estructura:
x1 <- 2 + 2
x1
## [1] 4
assign("x2", 3/6)
x2
## [1] 0.5
3*4 -> x3
x3
## [1] 12
Es importante enfatizar que hay muchos tipos (o clases) diferentes de objetos.
Volveremos a examinar el tema de “tipo” frente a “clase” más adelante. Por el momento, es útil simplemente nombrar algunos objetos con los que trabajaremos regularmente:
Cada clase de objeto tiene su propio conjunto de reglas (“métodos”) para determinar operaciones válidas. Por ejemplo, aunque hay operaciones que funcionan en matrices y dataframes, también hay algunas operaciones que solo funcionan en una matriz, y viceversa. Al mismo tiempo, puede (generalmente) convertir un objeto de un tipo a otro.
## Crea un dataframe llamado "df".
df = data.frame(x = 1:2, y = 3:4)
df
## x y
## 1 1 3
## 2 2 4
## Convertirlo en una matriz "mt".
mt = as.matrix(df)
mt
Puede inspeccionar/imprimir un objeto directamente en la consola debe
escribir df en la consola o puede usar la función
View(df) para verlo en el editor de datos.
Usar class, typeof, y str para
conocer más acerca de un objeto.
class(df) ## Evaluate its class.
[1] "data.frame"
typeof(df) ## Evaluate its type.
[1] "list"
str(df) ## Show its structure.
'data.frame': 2 obs. of 2 variables:
$ x: int 1 2
$ y: int 3 4
Podemos asignar objetos a diferentes nombres. Sin embargo, hay una serie de palabras especiales que están “reservadas” en R. Estos son comandos, operadores y relaciones fundamentales en base R que no se pueden (re)asignar (aunque se quisiera). Consulte una lista completa aquí.
Algunas de las palabras que no se pueden usar:
if
else
while
function
for
TRUE
FALSE
NULL
Inf
NaN
NA
Además de la lista de palabras estrictamente reservadas, existe otro conjunto de palabras que, aunque se reasignar pero que es mejor no usarlas.
Por ejemplo: c() se usa para concatenar; es decir, crear
vectores y unir diferentes objetos.
c <- 4
c(1, 2, 5)
Afortunadamente nada. R es lo suficientemente “inteligente” para
distinguir entre la variable c <- 4 que creamos y la
función integrada c() que requiere concatenación.
¿Qué pasa si usamos comillas para nombrar un objeto?
"hola" <- 2
hola
El workspace (o Global Environment) es la colección de objetos que viven en la memoria de la sesión actual de R. Allí se guardan los resultados que vas creando (vectores, data frames, modelos, funciones…). Al cerrar R, ese contenido se pierde salvo que se guarde explícitamente.
objects() # o ls(): lista de nombres de objetos
## [1] "df" "my_tbl" "x1" "x2" "x3"
ls()
## [1] "df" "my_tbl" "x1" "x2" "x3"
ls.str() # lista + mini estructura (útil para inspección rápida)
## df : 'data.frame': 2 obs. of 2 variables:
## $ x: int 1 2
## $ y: int 3 4
## my_tbl : tibble [7 × 3] (S3: tbl_df/tbl/data.frame)
## x1 : num 4
## x2 : num 0.5
## x3 : num 12
object.size(mtcars) # tamaño (bytes) de un objeto
## 7208 bytes
Para realizar tareas de “limpieza”: rm() elimina objetos
del workspace, pero sin nombres no borra nada; lo habitual es usar
rm(x, y) para quitar objetos concretos.
rm(list = ls()) vacía por completo el entorno global
(operación destructiva: se pierden todos los objetos de la sesión), por
lo que en material reproducible conviene marcarlo con
eval = FALSE y usarlo solo de forma consciente. Por último,
cat("\f") (form feed) limpia la consola de RStudio —solo la
pantalla—, sin afectar a los objetos en memoria.
rm() # remover un objeto del espacio de trabajo
rm(list=ls()) # Limpiar el entorno de trabajo
cat("\f") # Limpiar la consola
Los vectores y las matrices son objetos homogéneos. Es decir, todos los elementos de estos objeto deben ser del mismo tipo (numérico o carácter o lógico). Sin embargo, mientras los vectores son de una dimensión las matrices tienen dos dimensiones (filas y columnas).
Un vector es una secuencia ordenada de elementos del mismo
tipo.
Es la estructura más básica en R y se utiliza como base para construir
objetos más complejos como matrices y data frames.
La indexación es la forma en que se accede a los a elementos dentro
de un objeto. En R, comienza en 1. No en 0 como en algunos lenguajes
(por ejemplo, Python y JavaScript). Podemos usar [] para
indexar objetos que creamos en R.
a <- c(10 , 20 , 30 , 40 , 50 , 60)
a[4] # obtener el cuarto elemento del objeto "a"
[1] 40
a[2:3] # maneter elementos de la posición 2 a la 3
[1] 20 30
a[-3] # eliminar el tercer elemento
[1] 10 20 40 50 60
En R, además de acceder por posición, podemos seleccionar elementos usando condiciones lógicas.
Usando operadores lógicos:
x <- c(NA,1,2,3,4,5,NA)
x[!is.na(x)] # Diferentes de NA
## [1] 1 2 3 4 5
x[x>3] # Mayores a 3 (Ojo con los NA)
## [1] NA 4 5 NA
x[x %in% 1:3] # Contenidos en 1 a 3
## [1] 1 2 3
Los vectores permiten operaciones aritméticas de forma directa, aplicando el cálculo a todos sus elementos.
x <- 1:5 # x es un vector que contiene los números del 1 al 5 en orden ascendente
length(x) # largo del vector
## [1] 5
Algunos operadores que se pueden aplicar: +,
-, *, /, ^,
sum(), mean(), min()…
sum(x) # Suma total de los elementos
## [1] 15
prod(x) # Producto de todos los elementos
## [1] 120
mean(x) # Promedio
## [1] 3
min(x) # Mínimo
## [1] 1
max(x) # Máximo
## [1] 5
Una matriz en R es un objeto homogéneo de dos dimensiones (todas sus
celdas son del mismo tipo), esencialmente un vector al que se le añade
el atributo dim. Se construye con matrix()
indicando datos y dimensiones, y se llena por columnas de forma
predeterminada (puede cambiarse con byrow = TRUE). Se
accede con índice [i, j] (filas, columnas), y como
cualquier objeto en R puedes inspeccionarla con
attributes(), class() y str(). La
sustitución de valores funciona muy bien con indexación lógica (p. ej.,
asignar NA a todos los elementos < 4).
# Crear una matriz 3x3 con números del 1 al 9
x = matrix(data = 1:9 , nrow=3 , ncol=3, byrow = TRUE,
dimnames = list(c("Fila1", "Fila2", "Fila3"),
c("Col1", "Col2", "Col3")))
x
## Col1 Col2 Col3
## Fila1 1 2 3
## Fila2 4 5 6
## Fila3 7 8 9
En R, los atributos son metadatos que describen un objeto:
Para matrices, el atributo principal es dim, que indica
número de filas y número de columnas de una matriz.
Otros atributos comunes pueden ser nombres de filas
rownames y columnas colnames.
attributes(x) # atributos
## $dim
## [1] 3 3
##
## $dimnames
## $dimnames[[1]]
## [1] "Fila1" "Fila2" "Fila3"
##
## $dimnames[[2]]
## [1] "Col1" "Col2" "Col3"
class(x) # clase
## [1] "matrix" "array"
str(x) # tipo de dato
## int [1:3, 1:3] 1 4 7 2 5 8 3 6 9
## - attr(*, "dimnames")=List of 2
## ..$ : chr [1:3] "Fila1" "Fila2" "Fila3"
## ..$ : chr [1:3] "Col1" "Col2" "Col3"
rownames(x)
## [1] "Fila1" "Fila2" "Fila3"
En una matriz, los elementos se localizan usando el formato [i, j], donde i indica la fila y j la columna.
Tipos de indexación:
Numérica: usando números de posición (ej. x[2,3]).
Por nombre: si la matriz tiene nombres asignados (ej. x[“Fila1”, “Col1”]).
Lógica: usando condiciones que devuelvan TRUE/FALSE (ej. x[x > 5] devuelve todos los elementos mayores a 5).
x[1,] # Obtener la fila 1
## Col1 Col2 Col3
## 1 2 3
x[,3] # Obtener la columna 3
## Fila1 Fila2 Fila3
## 3 6 9
x[2,2] # Obtener elemento de la fila y columna 2a
## [1] 5
x[2, 3]# Indexación por posición numérica
## [1] 6
x["Fila1", "Col1"] # Indexación por nombre
## [1] 1
x[x > 5] # Indexación lógica
## [1] 7 8 6 9
Las matrices soportan indexación lógica, lo que permite filtrar y modificar elementos que cumplan ciertas condiciones.
x[x<4] = NA # Reemplaza por NA los valores menores a 4
x
## Col1 Col2 Col3
## Fila1 NA NA NA
## Fila2 4 5 6
## Fila3 7 8 9
Un data frame es una tabla de dos dimensiones (filas = observaciones, columnas = variables) donde cada columna es un vector del mismo largo y, por tanto, tiene un único tipo (numérico, carácter, lógico…), pero distintas columnas pueden tener tipos diferentes. Es la estructura base para manejar datos tabulares en R. Conjuntos de datos disponibles en memoria:
R incluye conjuntos de datos incorporados en el paquete
datasets.
## Checkear los conjuntos de datos que vienen por defecto en R
data(package="datasets")
df <- datasets::mtcars # 'mtcars' ya es un data frame
head(df) # imprimir las primeras filas
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
## Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
## Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
## Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
## Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
class(df) # clase del objeto
## [1] "data.frame"
dim(df) # filas y columnas
## [1] 32 11
colnames(df) # nombres de variables
## [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear"
## [11] "carb"
str(df) # estructura: tipos de columnas y muestra de valores
## 'data.frame': 32 obs. of 11 variables:
## $ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
## $ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
## $ disp: num 160 160 108 258 360 ...
## $ hp : num 110 110 93 110 175 105 245 62 95 123 ...
## $ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
## $ wt : num 2.62 2.88 2.32 3.21 3.44 ...
## $ qsec: num 16.5 17 18.6 19.4 17 ...
## $ vs : num 0 0 1 1 0 1 0 1 1 1 ...
## $ am : num 1 1 1 0 0 0 0 0 0 0 ...
## $ gear: num 4 4 4 3 3 3 3 4 4 4 ...
## $ carb: num 4 4 1 1 2 1 4 2 2 4 ...
En un data frame, los atributos más importantes son:
names o colnames: nombres de las
variables.
row.names: nombres de las observaciones (si
existen).
dim: dimensiones (número de filas y
columnas).
colnames(df) # acceder a los nombres de las variables/columnas
## [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear"
## [11] "carb"
attributes(df) # Ver atributos
## $names
## [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear"
## [11] "carb"
##
## $row.names
## [1] "Mazda RX4" "Mazda RX4 Wag" "Datsun 710"
## [4] "Hornet 4 Drive" "Hornet Sportabout" "Valiant"
## [7] "Duster 360" "Merc 240D" "Merc 230"
## [10] "Merc 280" "Merc 280C" "Merc 450SE"
## [13] "Merc 450SL" "Merc 450SLC" "Cadillac Fleetwood"
## [16] "Lincoln Continental" "Chrysler Imperial" "Fiat 128"
## [19] "Honda Civic" "Toyota Corolla" "Toyota Corona"
## [22] "Dodge Challenger" "AMC Javelin" "Camaro Z28"
## [25] "Pontiac Firebird" "Fiat X1-9" "Porsche 914-2"
## [28] "Lotus Europa" "Ford Pantera L" "Ferrari Dino"
## [31] "Maserati Bora" "Volvo 142E"
##
## $class
## [1] "data.frame"
dim(df) # dimensiones
## [1] 32 11
str(df) # Estructura
## 'data.frame': 32 obs. of 11 variables:
## $ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
## $ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
## $ disp: num 160 160 108 258 360 ...
## $ hp : num 110 110 93 110 175 105 245 62 95 123 ...
## $ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
## $ wt : num 2.62 2.88 2.32 3.21 3.44 ...
## $ qsec: num 16.5 17 18.6 19.4 17 ...
## $ vs : num 0 0 1 1 0 1 0 1 1 1 ...
## $ am : num 1 1 1 0 0 0 0 0 0 0 ...
## $ gear: num 4 4 4 3 3 3 3 4 4 4 ...
## $ carb: num 4 4 1 1 2 1 4 2 2 4 ...
Los dataframes tienen dos dimensiones [i,j], siendo
i y j la la i-ésima fila y j-ésima la columna
respectivamente.
df[1,] # Obtener la fila 1
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21 6 160 110 3.9 2.62 16.46 0 1 4 4
df[,3] # Obtener la columna 3
## [1] 160.0 160.0 108.0 258.0 360.0 225.0 360.0 146.7 140.8 167.6 167.6 275.8
## [13] 275.8 275.8 472.0 460.0 440.0 78.7 75.7 71.1 120.1 318.0 304.0 350.0
## [25] 400.0 79.0 120.3 95.1 351.0 145.0 301.0 121.0
df[1:3,1:4] # Acceder a las primeras 4 filas/columnas
## mpg cyl disp hp
## Mazda RX4 21.0 6 160 110
## Mazda RX4 Wag 21.0 6 160 110
## Datsun 710 22.8 4 108 93
df[2,2] # Obtener elemento de la fila y columa 2
## [1] 6
df$wt # Acceder a la variable wt
## [1] 2.620 2.875 2.320 3.215 3.440 3.460 3.570 3.190 3.150 3.440 3.440 4.070
## [13] 3.730 3.780 5.250 5.424 5.345 2.200 1.615 1.835 2.465 3.520 3.435 3.840
## [25] 3.845 1.935 2.140 1.513 3.170 2.770 3.570 2.780
💡A diferencia de las matrices, los data frames pueden mezclar tipos de datos por columna.
tibble() o data.frame()?Un tibble (paquete tibble, parte del
tidyverse) es una variante moderna del data.frame. Conserva
lo esencial para datos tabulares y cambia comportamientos que suelen
causar errores en principiantes: impresión más segura, subsetting
estable por tipo, reglas estrictas de reciclado y sin coincidencia
parcial de nombres. (Históricamente, además, nunca convertía caracteres
en factores; desde R ≥ 4.0, data.frame() tampoco lo hace
por defecto).
tibble imprime pocas
filas/columnas y muestra el tipo de cada variable;
data.frame intenta imprimir todo.[ un tibble
siempre devuelve otro tibble (no “colapsa” a vector);
en data.frame [ puede soltar
la dimensión (drop) si seleccionas 1 columna.tibble permite longitud 1 o exactamente
n filas; si no, error.
data.frame puede reciclar y hasta emitir
advertencias difíciles de notar.tibble
no hace coincidencia parcial con $ o
[[; data.frame puede hacerlo, provocando
errores silenciosos.require(tibble)
tb <- as_tibble(mtcars) # convertir a tibble
class(tb)
## [1] "tbl_df" "tbl" "data.frame"
df <- as.data.frame(tb) # volver a data.frame (si se necesita)
class(df)
## [1] "data.frame"
Las listas son objetos heterogéneos de una dimensión. Es decir, en una lista se puede almacenar diferentes tipos de objetos (vectores, matrices, dataframes y listas) pero al igual que los vectores tienen solo una dimensión (fila o columna).
lista = list("tibble_1"=tb[1:5,],
"tibble_2"=tb[6:10,]) # Asignar nombre a cada posición dentro de la lista
lista[[3]] = tb[11:nrow(tb),] # Almacenar en la tercera posición
lista
## $tibble_1
## # A tibble: 5 × 11
## mpg cyl disp hp drat wt qsec vs am gear carb
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4
## 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4
## 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1
## 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
## 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
##
## $tibble_2
## # A tibble: 5 × 11
## mpg cyl disp hp drat wt qsec vs am gear carb
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
## 2 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
## 3 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
## 4 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2
## 5 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4
##
## [[3]]
## # A tibble: 22 × 11
## mpg cyl disp hp drat wt qsec vs am gear carb
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 17.8 6 168. 123 3.92 3.44 18.9 1 0 4 4
## 2 16.4 8 276. 180 3.07 4.07 17.4 0 0 3 3
## 3 17.3 8 276. 180 3.07 3.73 17.6 0 0 3 3
## 4 15.2 8 276. 180 3.07 3.78 18 0 0 3 3
## 5 10.4 8 472 205 2.93 5.25 18.0 0 0 3 4
## 6 10.4 8 460 215 3 5.42 17.8 0 0 3 4
## 7 14.7 8 440 230 3.23 5.34 17.4 0 0 3 4
## 8 32.4 4 78.7 66 4.08 2.2 19.5 1 1 4 1
## 9 30.4 4 75.7 52 4.93 1.62 18.5 1 1 4 2
## 10 33.9 4 71.1 65 4.22 1.84 19.9 1 1 4 1
## # ℹ 12 more rows
Las listas también tienen atributos que permiten identificar y manipular sus elementos. Los más comunes son:
length(): número de elementos de la lista.
names(): nombres de los elementos (si los
tienen).
attributes(): metadatos del objeto.
length(lista) # dimensiones
## [1] 3
names(lista) # nombres de los elementos
## [1] "tibble_1" "tibble_2" ""
names(lista)[3] = "tibble_3" # Asignar nombre al elemento 3
attributes(lista) # Ver atributos
## $names
## [1] "tibble_1" "tibble_2" "tibble_3"
Para acceder a los elementos de una lista, R ofrece varias opciones:
[ ]: devuelve una sublista (mantiene la estructura
lista).
[[ ]]: devuelve el elemento en sí (acceso
profundo).
$nombre: acceso directo si el elemento tiene
nombre.
lista[[4]] = letters # Asigna el vector 'letters'(predefinido) como el cuarto elemento de la lista
head(lista)
## $tibble_1
## # A tibble: 5 × 11
## mpg cyl disp hp drat wt qsec vs am gear carb
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4
## 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4
## 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1
## 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
## 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
##
## $tibble_2
## # A tibble: 5 × 11
## mpg cyl disp hp drat wt qsec vs am gear carb
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
## 2 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
## 3 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
## 4 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2
## 5 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4
##
## $tibble_3
## # A tibble: 22 × 11
## mpg cyl disp hp drat wt qsec vs am gear carb
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 17.8 6 168. 123 3.92 3.44 18.9 1 0 4 4
## 2 16.4 8 276. 180 3.07 4.07 17.4 0 0 3 3
## 3 17.3 8 276. 180 3.07 3.73 17.6 0 0 3 3
## 4 15.2 8 276. 180 3.07 3.78 18 0 0 3 3
## 5 10.4 8 472 205 2.93 5.25 18.0 0 0 3 4
## 6 10.4 8 460 215 3 5.42 17.8 0 0 3 4
## 7 14.7 8 440 230 3.23 5.34 17.4 0 0 3 4
## 8 32.4 4 78.7 66 4.08 2.2 19.5 1 1 4 1
## 9 30.4 4 75.7 52 4.93 1.62 18.5 1 1 4 2
## 10 33.9 4 71.1 65 4.22 1.84 19.9 1 1 4 1
## # ℹ 12 more rows
##
## [[4]]
## [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
## [20] "t" "u" "v" "w" "x" "y" "z"
Se pueden remover elementos asignando NULL o usando
indexación negativa.
lista = lista[-4] # Elimina el cuarto elemento de la lista
head(lista)
## $tibble_1
## # A tibble: 5 × 11
## mpg cyl disp hp drat wt qsec vs am gear carb
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4
## 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4
## 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1
## 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
## 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
##
## $tibble_2
## # A tibble: 5 × 11
## mpg cyl disp hp drat wt qsec vs am gear carb
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
## 2 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
## 3 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
## 4 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2
## 5 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4
##
## $tibble_3
## # A tibble: 22 × 11
## mpg cyl disp hp drat wt qsec vs am gear carb
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 17.8 6 168. 123 3.92 3.44 18.9 1 0 4 4
## 2 16.4 8 276. 180 3.07 4.07 17.4 0 0 3 3
## 3 17.3 8 276. 180 3.07 3.73 17.6 0 0 3 3
## 4 15.2 8 276. 180 3.07 3.78 18 0 0 3 3
## 5 10.4 8 472 205 2.93 5.25 18.0 0 0 3 4
## 6 10.4 8 460 215 3 5.42 17.8 0 0 3 4
## 7 14.7 8 440 230 3.23 5.34 17.4 0 0 3 4
## 8 32.4 4 78.7 66 4.08 2.2 19.5 1 1 4 1
## 9 30.4 4 75.7 52 4.93 1.62 18.5 1 1 4 2
## 10 33.9 4 71.1 65 4.22 1.84 19.9 1 1 4 1
## # ℹ 12 more rows
Se puede acceder a elementos por posición o nombre.
lista[[1]] # usando la posición del elemento
## # A tibble: 5 × 11
## mpg cyl disp hp drat wt qsec vs am gear carb
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4
## 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4
## 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1
## 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
## 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
lista[[1]][,"mpg"] # dentro del objeto
## # A tibble: 5 × 1
## mpg
## <dbl>
## 1 21
## 2 21
## 3 22.8
## 4 21.4
## 5 18.7
lista[["tibble_1"]] # Usando el nombre del elemento
## # A tibble: 5 × 11
## mpg cyl disp hp drat wt qsec vs am gear carb
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4
## 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4
## 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1
## 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
## 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
Cuando los elementos de la lista son tablas (data frames o tibbles), se pueden combinar en un único objeto con rbindlist del paquete data.table. Esto es útil cuando se tienen varios fragmentos de datos que queremos apilar en un único dataframe o tibble:
# Combina la lista en una sola tabla alineando columnas por nombre
tbl = data.table::rbindlist(l = lista , use.names = T)
head(tbl)
## mpg cyl disp hp drat wt qsec vs am gear carb
## 1: 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
## 2: 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
## 3: 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
## 4: 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
## 5: 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
## 6: 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
class(tbl)
## [1] "data.table" "data.frame"
Piense en al menos 2 diferencias entre un vector,
una matriz y un dataframe
Dado a <- c(10, 20, 30, 40, 50), ¿qué devuelven
estas expresiones?
a[3]a[2:4]a[-1]W. N. Venables, D. M. Smith, 2025. An Introduction to R [Ver aquí]