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.
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).
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.
# 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
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
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
# 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']
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
# 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}
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.
# 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
# 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)
# 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
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
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
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
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
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"
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.
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.