02: R setup

Virtual

Autor/a

Victor Adrian

Fecha de publicación

2026-03-20

Código
# Configurando opciones globales para doc
# Para más info ver https://github.com/rstudio/cheatsheets/blob/main/rmarkdown-2.0.pdf
knitr::opts_chunk$set(echo = TRUE, error = TRUE, eval = TRUE, include=TRUE)

Esta clase trata las capacidades de R frente a otras herramientas y guía la configuración de RStudio, Colab y GitHub. Tras cubrir los fundamentos del lenguaje —desde tipos de datos hasta funciones básicas—, la teoría se consolida mediante la resolución de ejercicios prácticos.

¿Qué tiene R y no Excel, Stata o Python?

  • Es gratuito -> no Excel (versión de escritorio) ni Stata
  • Muy buena visualización (ggplot2, shiny) -> mejor que Excel y Stata, y un poco que Python
  • Capaz de analizar grandes volúmenes de datos (+1M de filas) -> no Excel (ligado a hardware)
  • Comunidad grande, lo que implica un mayor número de paquetes y librerías -> no Excel ni Stata, Python es más amplio y diverso
  • Curva de aprendizaje moderada -> baja en Excel

Cotejo vs. Python

Ambos son lenguajes de programación FOSS (Free and Open Source Software) con una gran variedad de paquetes para ciencias de datos, pero R está enfocado a la estadística y es preferido para tareas de ramas como la econometría. Python, por su parte, tiene una gama más amplia de fines (desarrollo web, apps, juegos, machine learning e IA).

Instalación

Respecto a este punto, recomiendo ver directamente las diapositivas de la clase 02. Yo usaré VS Code como IDE (análogo a RStudio) y conda (administrador de ambientes y paquetes multiplataforma) para correr R en entornos compartamentalizados dedicados, sin tener R siempre activo en mi variable PATH del sistema.

Esto facilita el uso de distintas versiones de R para diversos proyectos, cada uno con sus propios paquetes; además de manejar automáticamente cualquier problema en sus dependencias, al instalar nuevos y actualizar o desinstalar viejos paquetes. También facilita la transmisión exacta de ambientes a cualquiera que use conda, de nuevo, sin pedirle que instale R en todo su sistema o a nivel usuario.

Tampoco uso la versión de escritorio de GitHub, sola la web, con gh y git, herramientas que usan la terminal como interfaz (comandos, parámetros y argumentos) para interactuar con repositorios.

Variables y estructuras de datos

En la nota de la clase 01 definí qué es una variable y qué son las estructuras de datos, así que acá me limitaré a dar otros ejemplos en R.

Lista

Asignación

Código
verdad <- TRUE
nro_1 <- 50
nro_2 <- "sesenta"
nro_3 <- 4.3

# Para asignar valores también vale el "="
lista_sin_nombres = list(verdad, nro_1, nro_2, nro_3)

# `cat` separa los argumentos con un espacio, por eso el `sep = ""` para poner el punto final, pero hay que agregar los espacios manualmente.
cat("lista_sin_nombres: ")
str(lista_sin_nombres)
cat("Los nombres de sus elementos son: ",
    if (is.null(names(lista_sin_nombres))) "no tienen nombres" else paste(names(lista_sin_nombres), collapse = ", "),
    ".", sep = "", "\n\n"
    )

lista_con_nombres = list(logico = verdad, entero= nro_1, texto = nro_2, real = nro_3)
cat("lista_con_nombres: ")
str(lista_con_nombres)
cat("Los nombres de sus elementos son: ",
    if (is.null(names(lista_con_nombres))) "no tienen nombres" else paste(names(lista_con_nombres), collapse = ", "),
    ".", sep = "", "\n\n"
    )
lista_sin_nombres: List of 4
 $ : logi TRUE
 $ : num 50
 $ : chr "sesenta"
 $ : num 4.3
Los nombres de sus elementos son: no tienen nombres.

lista_con_nombres: List of 4
 $ logico: logi TRUE
 $ entero: num 50
 $ texto : chr "sesenta"
 $ real  : num 4.3
Los nombres de sus elementos son: logico, entero, texto, real.

Acceso

Por índice/posición
Código
cat("Elemento en cuarta posición:", lista_con_nombres[[4]])
cat("\nClase de elemento:", class(lista_con_nombres[[4]]))
Elemento en cuarta posición: 4.3
Clase de elemento: numeric
Por nombre
Código
cat("Elementos lógico y real:\n\n")
lista_con_nombres[c("logico", "real")]
cat("Clase de elementos:", class(lista_con_nombres[c("logico", "real")]))
Elementos lógico y real:

$logico
[1] TRUE

$real
[1] 4.3

Clase de elementos: list

Vector

Asignación

Como ya vimos, los vectores son secuencias ordenadas de igual tipo. Pero, ¿cómo logran esto?

Esta clase de vector, llamada atómico, se logra gracias a la coerción de los tipos de datos que componen la secuencia a uno en común. La función combine/concatenate es la responsable, puesto que si R detecta que mezclas tipos con c(), devolverá un vector tras aplicar la coerción al tipo común más general de entre los elementos. Según, de más a menos general:

character > complex > double > integer > logical

Porque sus elementos son de igual tipo, se define a estos vectores como estructuras homogéneas.

Código
cat("Clase de cada elemento de lista_sin_nombres:\n")
sapply(lista_sin_nombres, class)

cat("\nDefino un vector atómico a partir de las variables originales:\n")
vector = c(verdad, nro_1, nro_2, nro_3)
cat("vector =", paste(vector, collapse = ", " ))

cat("\n\nClase de los mismos elementos, pero esta vez en 'vector':\n")
sapply(vector, class)
Clase de cada elemento de lista_sin_nombres:
[1] "logical"   "numeric"   "character" "numeric"  

Defino un vector atómico a partir de las variables originales:
vector = TRUE, 50, sesenta, 4.3

Clase de los mismos elementos, pero esta vez en 'vector':
       TRUE          50     sesenta         4.3 
"character" "character" "character" "character" 

Nota 1: Se coerce usando las siguientes funciones: as.integer(), as.double()/as.numeric(), as.complex(), as.character(), as.list().

Acceso

Por índice/posición
Código
cat("Elemento en cuarta posición:", vector[4])
cat("\nElementos en primera y cuarta posición:", paste(vector[c(1, 4)], collapse = ", "))
cat("\nElementos en segunda, tercera y cuarta posición:", paste(vector[2:4], collapse = ", "))
Elemento en cuarta posición: 4.3
Elementos en primera y cuarta posición: TRUE, 4.3
Elementos en segunda, tercera y cuarta posición: 50, sesenta, 4.3

Data frame

Asignación

Código
id_producto = 1:5
precio_producto = round(runif(5, min = 5, max = 100), 2)
df = data.frame(id_producto = id_producto, precio_producto = precio_producto)
cat("Data frame:\n")
df
Data frame:
  id_producto precio_producto
1           1           22.54
2           2           30.98
3           3           84.77
4           4           87.38
5           5           71.37

Acceso

Por columna
Código
cat("Columna 'precio_producto' como vector:\n")
df$precio_producto # igual que df[[ "precio_producto" ]]
cat("Clase:", class(df$precio_producto))
cat("\n\nColumna 'id_producto' como data frame:\n")
df[1]
cat("Clase:", class(df[1]))
Columna 'precio_producto' como vector:
[1] 22.54 30.98 84.77 87.38 71.37
Clase: numeric

Columna 'id_producto' como data frame:
  id_producto
1           1
2           2
3           3
4           4
5           5
Clase: data.frame
Por fila
Código
cat("Filas dos y cuatro como vector:\n")
unlist(df[c(2, 4), ])
cat("\nVerifico coerción a tipo más general:\n")
sapply(unlist(df[c(2, 4), ]), class)
Filas dos y cuatro como vector:
    id_producto1     id_producto2 precio_producto1 precio_producto2 
            2.00             4.00            30.98            87.38 

Verifico coerción a tipo más general:
    id_producto1     id_producto2 precio_producto1 precio_producto2 
       "numeric"        "numeric"        "numeric"        "numeric" 
Código
cat("Filas uno y dos como data frame:\n")
df[1:2, ]
cat("\nFilas uno, tres y cuatro como data frame:\n")
df[c(1, 3:4), ]
Filas uno y dos como data frame:
  id_producto precio_producto
1           1           22.54
2           2           30.98

Filas uno, tres y cuatro como data frame:
  id_producto precio_producto
1           1           22.54
3           3           84.77
4           4           87.38
Código
cat("Filas dos, cuatro y cinco como lista:\n")
as.list(df[c(2, 4:5), ])
cat("\nVerifico clase:\n")
sapply(df[c(2, 4:5), ], class)
Filas dos, cuatro y cinco como lista:
$id_producto
[1] 2 4 5

$precio_producto
[1] 30.98 87.38 71.37


Verifico clase:
    id_producto precio_producto 
      "integer"       "numeric" 
Por fila y columna
Código
cat("Fila cuatro, columna 'precio_producto' por nombre:\n")
df[4, c("precio_producto")] # igual que df$precio_producto[4]
class(df[4, c("precio_producto")])
cat("\nFilas cuatro y cinco, columna 'id_producto' por posición:\n")
df[4:5, c(1)]
sapply(df[4:5, c(1)], class)
Fila cuatro, columna 'precio_producto' por nombre:
[1] 87.38
[1] "numeric"

Filas cuatro y cinco, columna 'id_producto' por posición:
[1] 4 5
[1] "integer" "integer"

Nota 2: Llamar más de una columna convertiría el resultado de valor o vector atómico a data frame.

Matriz

Asignación

Código
m1 = matrix(sample(5:20, size = 9, replace = TRUE), nrow = 3, ncol = 3)
cat("Matriz 'm1' populada por columna:\n")
m1

m2 = matrix(1:9, nrow = 3, byrow = TRUE)
cat("\nMatriz 'm2' populada por fila:\n")
m2

m3 = round(runif(6, min = 0, max = 1), 2)
cat("\nVector aleatorio:\n")
m3
dim(m3) = c(2, 3)
cat("\nMatriz 'm3' generada a partir de vector aleatorio, populada por columna:\n")
m3
Matriz 'm1' populada por columna:
     [,1] [,2] [,3]
[1,]   17    8   12
[2,]   11   18    7
[3,]   17   10    9

Matriz 'm2' populada por fila:
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9

Vector aleatorio:
[1] 0.45 0.78 0.80 0.16 0.47 0.20

Matriz 'm3' generada a partir de vector aleatorio, populada por columna:
     [,1] [,2] [,3]
[1,] 0.45 0.80 0.47
[2,] 0.78 0.16 0.20

Acceso

Por índice/posición
Código
cat("Elemento en F2C2 de 'm2':\n")
m2[2, 2]
cat("\nElementos en C2 de 'm2', como vector:\n")
m2[, 2]
cat("\nElementos en C2 de 'm2', como submatriz:\n")
m2[, 2, drop = FALSE]
cat("\nElementos en F1/F2 y C1/C3 de 'm2', como submatriz:\n")
m2[c(1, 2), c(1, 3)]
Elemento en F2C2 de 'm2':
[1] 5

Elementos en C2 de 'm2', como vector:
[1] 2 5 8

Elementos en C2 de 'm2', como submatriz:
     [,1]
[1,]    2
[2,]    5
[3,]    8

Elementos en F1/F2 y C1/C3 de 'm2', como submatriz:
     [,1] [,2]
[1,]    1    3
[2,]    4    6
Por nombre
Código
rownames(m3) = c("r1", "r2")
colnames(m3) = c("a", "b", "c")
cat("Elementos en columna 'c' de 'm3' como vector:\n")
m3[, "c"]
cat("\nElementos en columna 'c' de 'm3' como submatriz:\n")
m3[, "c", drop = FALSE]
Elementos en columna 'c' de 'm3' como vector:
  r1   r2 
0.47 0.20 

Elementos en columna 'c' de 'm3' como submatriz:
      c
r1 0.47
r2 0.20

Nota 3: Se puede convertir de matriz a data frame y viceversa con as.data.frame() y as.matrix(), respectivamente.

Código
cat("Convierto 'm1' a data frame:\n")
df_from_m1 = as.data.frame(m1)
df_from_m1
cat("Clase:", class(df_from_m1))
Convierto 'm1' a data frame:
  V1 V2 V3
1 17  8 12
2 11 18  7
3 17 10  9
Clase: data.frame

Operadores

Tipo Descripción Símbolo
Aritmético Suma +
Aritmético Resta -
Aritmético Multiplicación *
Aritmético División /
Aritmético Potencia ^
Aritmético Módulo %%
Comparación Igual ==
Comparación Distinto !=
Comparación Mayor >
Comparación Menor <
Comparación Mayor o igual >=
Comparación Menor o igual <=
Lógico Y &
Lógico O |
Lógico NO !
Lógico Inclusión %in%

Funciones básicas

Sum

Código
cat("Suma elementos de C3 de 'm2':", sum(m2[, 3]))
Suma elementos de C3 de 'm2': 18

Mean

Código
cat("Promedio de precios de columna 'precio_producto':", mean(df$precio_producto))
Promedio de precios de columna 'precio_producto': 59.408

Length

Código
cat("Cantidad de elementos que componen a 'vector':", length(vector))
Cantidad de elementos que componen a 'vector': 4

Class

Código
cat("Clase de 'lista_sin_nombres':", class(lista_sin_nombres))
cat("\n\nClase de cada elemento de 'lista_sin_nombres':\n")
sapply(lista_sin_nombres, class)
Clase de 'lista_sin_nombres': list

Clase de cada elemento de 'lista_sin_nombres':
[1] "logical"   "numeric"   "character" "numeric"  

Tipos de archivo (extensión)

R

  • Extensión .R
  • Se ejecuta línea por línea o por bloque (RStudio detecta automática los bloques)
  • Útil para scripts, funciones y automatización
  • Admite comentarios con #

Rmd

  • Extensión .Rmd
  • Acepta Markdown (un lenguaje ligero que permite añadir formato a documentos de texto plano)
  • Si la aplicación de Markdown lo permite, también acepta HTML tags
  • Guarda y ejecuta código dentro de chunks
  • Ideal para generar y compartir reportes de alta calidad, aun interactivos
  • Capaz de adaptar outputs a presentaciones, documentos y más

Ayuda en R

Diapositiva de clase 02
Imagen obtenida de diapositivas de clase 02.

Ejercicios

Código
# Ejercicio 1.1
cat("Ejercicio 1.1:")
pais = "Uruguay"
poblacion = 3.4
anio_censo = 2023L
es_mercosur = TRUE
cat("\nclase 'pais':", class(pais))
cat("\nclase 'poblacion':", class(poblacion))
cat("\nclase 'anio_censo':", class(anio_censo))
cat("\nclase 'es_mercosur':", class(es_mercosur))

# Ejercicio 1.2
cat("\n\nEjercicio 1.2:")
pbi = 77.2
pbi_check = 77.2 * (10^9)
poblacion_check = 3.4 * (10^6)
pbi_pc = 77.2 / (3.4 / 1000)
cat("\nEl pbi per cápita de Uruguay son: USD", pbi_pc)
Ejercicio 1.1:
clase 'pais': character
clase 'poblacion': numeric
clase 'anio_censo': integer
clase 'es_mercosur': logical

Ejercicio 1.2:
El pbi per cápita de Uruguay son: USD 22705.88
Código
# Ejercicio 1.3
# cat("Ejercicio 1.3:")
mi_variable = 10
cat("\n\nLlamando a 'Mi_Variable':", Mi_Variable)
Error: object 'Mi_Variable' not found
Código
# Ejercio 2.1
cat("Ejercicio 2.1:")
paises = c("Argentina", "Brasil", "Paraguay", "Uruguay", "Venezuela")
poblaciones = c(46, 214, 7, 3.4, 28) # en millones
cat("\nVector 'paises':", paste(paises, collapse = ", "))
cat("\nVector 'poblaciones' en millones:", paste(poblaciones, collapse = ", "))

# Ejercicio 2.2
cat("\n\nEjercicio 2.2:")
cat("\nTercer elemento de 'paises':", paises[3])
cat("\nElementos uno, dos y cuatro de 'poblaciones':", paste(poblaciones[c(1:2,4)], collapse = ", "))
cat("\nMostrar todos los países excepto el último:", paste(paises[1:(length(paises)-1)], collapse = ", "))

# Ejercicio 2.3
cat("\n\nEjercicio 2.3:")
anios = 2000:2024
cat("\nEl vector 'anios' tiene", length(anios), "elementos")

# Ejercicio 2.4
cat("\n\nEjercicio 2.4:")
cat("\nLa población total del Mercosur es de", sum(poblaciones), "millones")
cat("\nLa población promedio del Mercosur es de", mean(poblaciones), "millones")
cat("\nEl país con mayor población es ", paises[which.max(poblaciones)], ", con ",(max(poblaciones)), " millones", sep ="")

# Ejercicio 2.5
cat("\n\nEjercicio 2.5:")
cat("\nLos países con más de 10 millones de habitantes son:", paste(paises[poblaciones > 10], collapse = ", "))
Ejercicio 2.1:
Vector 'paises': Argentina, Brasil, Paraguay, Uruguay, Venezuela
Vector 'poblaciones' en millones: 46, 214, 7, 3.4, 28

Ejercicio 2.2:
Tercer elemento de 'paises': Paraguay
Elementos uno, dos y cuatro de 'poblaciones': 46, 214, 3.4
Mostrar todos los países excepto el último: Argentina, Brasil, Paraguay, Uruguay

Ejercicio 2.3:
El vector 'anios' tiene 25 elementos

Ejercicio 2.4:
La población total del Mercosur es de 298.4 millones
La población promedio del Mercosur es de 59.68 millones
El país con mayor población es Brasil, con 214 millones

Ejercicio 2.5:
Los países con más de 10 millones de habitantes son: Argentina, Brasil, Venezuela
Código
# Ejercicio opcional
cat("Ejercicio opcional:\n\n")
nombre = c("a", "b", "c", "d", "e")
precio = sample(800:1300, size = 5, replace = TRUE)
stock = sample(5:30, size = 5, replace = TRUE)
categoria = c("local", "importado", "local", "importado", "local")
supermercado = data.frame(nombre, categoria, stock, precio)

# 1
cat("1. Mostrar solo productos con precio mayor a 1000:\n")
supermercado[supermercado$precio > 1000, ] # o subset(supermercado, precio > 1000)

# 2
cat("\n2. Calcular el valor total de stock y agregarlo como columna:\n")
supermercado$valor_stock = supermercado$stock * supermercado$precio
supermercado

# 3
cat("\n3. El valor total del inventario es:", sum(supermercado$valor_stock))

# 4
cat("\n\n4. El precio promedio de la categoría 'local' es", round(sum(supermercado$valor_stock[supermercado$categoria == "local"]) / sum(supermercado$stock[supermercado$categoria == "local"]), 2), "y el de 'importado' es", round(sum(supermercado$valor_stock[supermercado$categoria == "importado"]) / sum(supermercado$stock[supermercado$categoria == "importado"]), 2))
Ejercicio opcional:

1. Mostrar solo productos con precio mayor a 1000:
  nombre categoria stock precio
1      a     local    14   1201
2      b importado    28   1185
3      c     local    11   1109
4      d importado    17   1124

2. Calcular el valor total de stock y agregarlo como columna:
  nombre categoria stock precio valor_stock
1      a     local    14   1201       16814
2      b importado    28   1185       33180
3      c     local    11   1109       12199
4      d importado    17   1124       19108
5      e     local    25    943       23575

3. El valor total del inventario es: 104876

4. El precio promedio de la categoría 'local' es 1051.76 y el de 'importado' es 1161.96