Pregunta 1 (1.5 puntos) - Conceptos básicos

Parte A (0.75 puntos): Explica brevemente las diferencias entre un vector en R y una lista en Python. Menciona al menos dos características distintivas de cada uno.

Vector en R:

Es una estructura homogénea: todos los elementos deben ser del mismo tipo (numérico, carácter, lógico…).

Operaciones vectorizadas: sumar/operar con todo el vector aplica elemento a elemento de forma nativa.

Lista en Python:

Estructura heterogénea: puede contener objetos de distintos tipos en la misma lista.

Dinámica y mutable: se pueden agregar, quitar o reasignar elementos fácilmente y tiene métodos integrados (append, pop, etc).

Parte B (0.75 puntos): ¿Cuál es la principal diferencia entre un DataFrame en Python (pandas) y un data.frame en R en términos de indexación?

En pandas cada fila tiene un index explícito que puede ser cualquier etiqueta (no necesariamente 0..n-1) y se usa para selección por etiqueta (.loc) o por posición (.iloc).

En R (data.frame) la indexación por filas es posicional y se hace con corchetes [fila, columna] o con nombres ($columna); existe row.names pero no es tan central como el index de pandas.

Pregunta 2 (1.5 puntos) - Estructuras de datos en R

# Datos dados
numeros <- c(10, 25, 30, 15, 40)
nombres <- c("Ana", "Bruno", "Carlos", "Diana", "Elena")
edades <- c(22, 25, 23, 24, 22)

# a) ¿Qué tipo de estructura es 'numeros'?
class(numeros)   # "numeric" -> vector numérico
## [1] "numeric"
# b) Crear data.frame 'estudiantes' que combine nombres, edades, numeros (columna "notas")
estudiantes <- data.frame(
  nombre = nombres,
  edad = edades,
  notas = numeros,
  stringsAsFactors = FALSE
)
estudiantes
##   nombre edad notas
## 1    Ana   22    10
## 2  Bruno   25    25
## 3 Carlos   23    30
## 4  Diana   24    15
## 5  Elena   22    40
# c) ¿Cómo acceder al nombre del tercer estudiante?
# Opción 1 (vector original):
nombres[3]       # "Carlos"
## [1] "Carlos"
# Opción 2 (data.frame):
estudiantes$nombre[3]   # "Carlos"
## [1] "Carlos"
estudiantes[3, "nombre"]# también "Carlos"
## [1] "Carlos"
if (!requireNamespace("reticulate", quietly = TRUE)) {
  install.packages("reticulate")
}

library(reticulate)

# Instalar pandas (si no existe ya en el entorno de Python)
py_install("pandas", pip = TRUE)
## Using virtual environment "C:/Users/FLAVIO/AppData/Local/R/cache/R/reticulate/uv/cache/archive-v0/bSNFJpAHH8s6VfQs1fDW3" ...
## + "C:/Users/FLAVIO/AppData/Local/R/cache/R/reticulate/uv/cache/archive-v0/bSNFJpAHH8s6VfQs1fDW3/Scripts/python.exe" -m pip install --upgrade --no-user pandas
# Importar pandas
pd <- import("pandas")

# Acceder a la versión correctamente como string
version_pandas <- py_to_r(pd$`__version__`)
cat("Versión de pandas instalada:", version_pandas, "\n")
## Versión de pandas instalada: 2.3.2

Pregunta 3 (2 puntos) - Estructuras de datos en Python

import pandas as pd

# a) Crear DataFrame con la información
datos = {
    'producto': ['Laptop', 'Mouse', 'Teclado', 'Monitor', 'Auriculares'],
    'precio': [1200, 25, 75, 300, 150],
    'stock': [10, 50, 30, 15, 25]
}
df = pd.DataFrame(datos)
print("=== DataFrame ===")
## === DataFrame ===
print(df)
##       producto  precio  stock
## 0       Laptop    1200     10
## 1        Mouse      25     50
## 2      Teclado      75     30
## 3      Monitor     300     15
## 4  Auriculares     150     25
# b) Mostrar solo productos con precio mayor a 100
print("\n=== Productos con precio > 100 ===")
## 
## === Productos con precio > 100 ===
print(df[df['precio'] > 100])
##       producto  precio  stock
## 0       Laptop    1200     10
## 3      Monitor     300     15
## 4  Auriculares     150     25
# c) Calcular el precio promedio de todos los productos
precio_promedio = df['precio'].mean()
print("\n=== Precio promedio ===")
## 
## === Precio promedio ===
print(precio_promedio)
## 350.0
# d) Agregar nueva columna 'categoria'
df['categoria'] = ['Computadora', 'Accesorio', 'Accesorio', 'Computadora', 'Accesorio']
print("\n=== DataFrame con columna 'categoria' ===")
## 
## === DataFrame con columna 'categoria' ===
print(df)
##       producto  precio  stock    categoria
## 0       Laptop    1200     10  Computadora
## 1        Mouse      25     50    Accesorio
## 2      Teclado      75     30    Accesorio
## 3      Monitor     300     15  Computadora
## 4  Auriculares     150     25    Accesorio

Pregunta 4 (2 puntos) - Control de flujo en R

categorizar_notas <- function(notas) {
  # Valida entrada
  sapply(notas, function(n) {
    if (is.na(n)) return(NA_character_)
    if (!is.numeric(n)) return(NA_character_)
    if (n >= 18 && n <= 20) {
      "Excelente"
    } else if (n >= 15 && n < 18) {
      "Bueno"
    } else if (n >= 11 && n < 15) {
      "Regular"
    } else if (n >= 0 && n < 11) {
      "Deficiente"
    } else {
      NA_character_
    }
  }, USE.NAMES = FALSE)
}

# Prueba
notas_prueba <- c(19, 12, 16, 8, 20, 14)
categorias_prueba <- categorizar_notas(notas_prueba)
data.frame(nota = notas_prueba, categoria = categorias_prueba)
##   nota  categoria
## 1   19  Excelente
## 2   12    Regular
## 3   16      Bueno
## 4    8 Deficiente
## 5   20  Excelente
## 6   14    Regular

Pregunta 5 (2 puntos) - Control de flujo en Python

# Inventario dado
inventario = {
    'manzanas': 50,
    'naranjas': 30,
    'plátanos': 0,
    'uvas': 20
}

# a) Bucle for para mostrar cada producto y su cantidad
print("Listado de inventario:")
## Listado de inventario:
for producto, cantidad in inventario.items():
    print(f"- {producto}: {cantidad}")
## - manzanas: 50
## - naranjas: 30
## - plátanos: 0
## - uvas: 20
# b) Identificar agotados (cantidad == 0) y bajo stock (cantidad < 25)
agotados = []
bajo_stock = []
for producto, cantidad in inventario.items():
    if cantidad == 0:
        print(f"AGOTADO: {producto}")
        agotados.append(producto)
    elif cantidad < 25:
        print(f"BAJO STOCK: {producto} (cantidad = {cantidad})")
        bajo_stock.append(producto)
## AGOTADO: plátanos
## BAJO STOCK: uvas (cantidad = 20)
# c) Lista con nombres que necesitan reabastecimiento (cantidad <= 25)
necesitan_reabastecer = [p for p, c in inventario.items() if c <= 25]
print("\nProductos que necesitan reabastecimiento (<=25):", necesitan_reabastecer)
## 
## Productos que necesitan reabastecimiento (<=25): ['plátanos', 'uvas']

Pregunta 6 (2.5 puntos) - Funciones en ambos lenguajes

Parte A - R (1.25 p)

estadisticas_basicas <- function(vector_numerico) {
  # Asegurar numeric y remover NA en cómputos
  v <- as.numeric(vector_numerico)
  v <- v[!is.na(v)]
  list(
    media = if(length(v) > 0) mean(v) else NA_real_,
    mediana = if(length(v) > 0) median(v) else NA_real_,
    minimo = if(length(v) > 0) min(v) else NA_real_,
    maximo = if(length(v) > 0) max(v) else NA_real_
  )
}

# Prueba
estadisticas_basicas(c(10, 15, 20, NA, 5))
## $media
## [1] 12.5
## 
## $mediana
## [1] 12.5
## 
## $minimo
## [1] 5
## 
## $maximo
## [1] 20

Parte B - Python (1.25 p)

# Función equivalente en Python (sin numpy)
import statistics

def estadisticas_basicas(lista_numeros):
    # Filtrar None/NA y convertir a float si es posible
    clean = [x for x in lista_numeros if x is not None]
    if len(clean) == 0:
        return {'media': None, 'mediana': None, 'minimo': None, 'maximo': None}
    return {
        'media': statistics.mean(clean),
        'mediana': statistics.median(clean),
        'minimo': min(clean),
        'maximo': max(clean)
    }

# Prueba
print(estadisticas_basicas([10, 15, 20, None, 5]))
## {'media': 12.5, 'mediana': 12.5, 'minimo': 5, 'maximo': 20}

Pregunta 7 (2.5 puntos) - Paquetes y librerías

Parte A (1 punto)

En R:

install.packages("paquete") descarga e instala el paquete desde CRAN (una sola vez en el sistema).

library(paquete) carga el paquete en la sesión actual (se ejecuta cada vez que se abre R si quieres usar el paquete).

En Python:

pip install paquete instala el paquete en el entorno Python (terminal, una sola vez).

import paquete carga el paquete en el script/entorno actual para usar sus funciones.

Parte B (1.5 p) — Código

# Instalar y cargar dplyr en R (si no está instalado, se instala)
if (!requireNamespace("dplyr", quietly = TRUE)) install.packages("dplyr")
library(dplyr)
## 
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
# Ejemplo de uso: crear un data.frame de ejemplo y filtrar
df_ej <- data.frame(nombre = c("A","B","C"), promedio = c(16, 14, 18))
df_filtrado <- df_ej %>% filter(promedio > 15)
df_ej
##   nombre promedio
## 1      A       16
## 2      B       14
## 3      C       18
df_filtrado
##   nombre promedio
## 1      A       16
## 2      C       18
# Instalar e importar pandas en Python (ejecutar pip en terminal si es necesario)
# En terminal: pip install pandas
import pandas as pd

# Ejemplo de uso: read_csv (mostramos el uso, no se lee archivo real aquí)
# df = pd.read_csv("archivo.csv")
# Ejemplo rápido:
df_ej = pd.DataFrame({'nombre': ['A','B','C'], 'promedio':[16,14,18]})
df_ej_filtered = df_ej[df_ej['promedio'] > 15]
print(df_ej)
##   nombre  promedio
## 0      A        16
## 1      B        14
## 2      C        18
print("\nFiltrado:")
## 
## Filtrado:
print(df_ej_filtered)
##   nombre  promedio
## 0      A        16
## 2      C        18

Pregunta 8 (2.5 puntos) - Lectura de datos

# Creamos un data.frame de ejemplo
estudiantes <- data.frame(
  nombre   = c("Ana", "Luis", "María", "José", "Lucía"),
  edad     = c(20, 22, 21, 23, 20),
  carrera  = c("Ing. Sistemas", "Medicina", "Derecho", "Contabilidad", "Psicología"),
  promedio = c(16, 14, 18, 12, 19),
  stringsAsFactors = FALSE
)

# Guardamos a CSV en la carpeta del proyecto (donde está tu .Rmd)
write.csv(estudiantes, "estudiantes.csv", row.names = FALSE)

a) (0.5 puntos) Escribe el código en R para leer el archivo “estudiantes.csv”

# Leer el archivo que acabamos de crear
estudiantes <- read.csv("estudiantes.csv", stringsAsFactors = FALSE)
head(estudiantes)
##   nombre edad       carrera promedio
## 1    Ana   20 Ing. Sistemas       16
## 2   Luis   22      Medicina       14
## 3  María   21       Derecho       18
## 4   José   23  Contabilidad       12
## 5  Lucía   20    Psicología       19

b) (0.5 puntos) Escribe el código en Python para leer el mismo archivo

import pandas as pd

df = pd.read_csv("estudiantes.csv", encoding="utf-8")
print(df.head())
##   nombre  edad        carrera  promedio
## 0    Ana    20  Ing. Sistemas        16
## 1   Luis    22       Medicina        14
## 2  María    21        Derecho        18
## 3   José    23   Contabilidad        12
## 4  Lucía    20     Psicología        19

c) (0.75 puntos) En R, filtra estudiantes con promedio > 15 usando dplyr

library(dplyr)

estudiantes_mayor_15 <- estudiantes %>%
  filter(promedio > 15)

estudiantes_mayor_15
##   nombre edad       carrera promedio
## 1    Ana   20 Ing. Sistemas       16
## 2  María   21       Derecho       18
## 3  Lucía   20    Psicología       19

d) (0.75 puntos) En Python, calcula el promedio por carrera usando pandas

import pandas as pd

# Leer el archivo (si no lo tienes en memoria desde antes)
df = pd.read_csv("estudiantes.csv", encoding="utf-8")

# Calcular el promedio de 'promedio' por 'carrera'
promedio_por_carrera = df.groupby("carrera")["promedio"].mean().reset_index()

print("=== Promedio por carrera ===")
## === Promedio por carrera ===
print(promedio_por_carrera)
##          carrera  promedio
## 0   Contabilidad      12.0
## 1        Derecho      18.0
## 2  Ing. Sistemas      16.0
## 3       Medicina      14.0
## 4     Psicología      19.0

e) (0.5 puntos) ¿Qué parámetro usarías si el archivo tiene problemas de codificación (tildes, ñ)?

En R (read.csv) → usar fileEncoding = "UTF-8" o fileEncoding = "latin1"

read.csv("estudiantes.csv", fileEncoding = "latin1")
##   nombre edad       carrera promedio
## 1    Ana   20 Ing. Sistemas       16
## 2   Luis   22      Medicina       14
## 3 María   21       Derecho       18
## 4  José   23  Contabilidad       12
## 5 Lucía   20   Psicología       19

En Python (pandas)

pd.read_csv("estudiantes.csv", encoding="latin1")
##    nombre  edad        carrera  promedio
## 0     Ana    20  Ing. Sistemas        16
## 1    Luis    22       Medicina        14
## 2  María    21        Derecho        18
## 3   José    23   Contabilidad        12
## 4  Lucía    20    Psicología        19

Pregunta 9 (2 puntos) - Problema integrador

departamentos <- c("Lima", "Arequipa", "La Libertad", "Piura", "Junín")
poblacion_2020 <- c(10628470, 1382730, 1905301, 2047954, 1246038)

df_peru <- data.frame(departamento = departamentos, poblacion_2020 = poblacion_2020, stringsAsFactors = FALSE)

# a) Porcentaje de la población total que representa cada departamento
total_pob <- sum(df_peru$poblacion_2020)
df_peru$porcentaje <- df_peru$poblacion_2020 / total_pob * 100

# b) Departamento más y menos poblado
mas_poblado <- df_peru$departamento[which.max(df_peru$poblacion_2020)]
menos_poblado <- df_peru$departamento[which.min(df_peru$poblacion_2020)]

# c) Categorización por densidad (según enunciado: >2M, 1-2M, <1M)
df_peru$densidad_categoria <- with(df_peru, ifelse(
  poblacion_2020 > 2000000, "Alta densidad",
  ifelse(poblacion_2020 >= 1000000 & poblacion_2020 <= 2000000, "Media densidad", "Baja densidad")
))

# Mostrar resultados
df_peru
##   departamento poblacion_2020 porcentaje densidad_categoria
## 1         Lima       10628470  61.755756      Alta densidad
## 2     Arequipa        1382730   8.034227     Media densidad
## 3  La Libertad        1905301  11.070578     Media densidad
## 4        Piura        2047954  11.899450      Alta densidad
## 5        Junín        1246038   7.239990     Media densidad
mas_poblado
## [1] "Lima"
menos_poblado
## [1] "Junín"

Pregunta 10 (1.5 puntos) - Análisis crítico

a) (0.75 p) Dos ventajas de R sobre Python para análisis estadístico

R fue diseñado para estadística: tiene sintaxis y estructuras (fórmulas, modelos lineales con lm, paquetes estadísticos avanzados en CRAN) pensadas para análisis estadístico.

Gran cantidad de paquetes especializados y maturez en métodos estadísticos y visualización (por ejemplo ggplot2, lme4, car, etc.) con convenciones estándar para investigación.

b) (0.75 p) Dos ventajas de Python sobre R para ciencia de datos en general

Ecosistema más amplio para producción y aplicaciones generales (integración web, APIs, despliegue), y mejor para ingeniería de datos y pipelines.

Librerías de ML/AI muy maduras y estandarizadas (scikit-learn, TensorFlow, PyTorch) y facilidad para usar Python en producción y sistemas distribuidos.