Estadística en R y Python

UNIVERSIDAD DE EL SALVADOR

FACULTAD MULTIDISCIPLINARIA DE OCCIDENTE

DEPARTAMENTO DE MATEMATICA

TAREA DE DATOS ESTADISTICOS

LIC.JAIME ISAAC PENA

ESMERALDA ARACELY MUNGUIA

SANTA ANA 3 DE OCTUBRE DE 2025

MEDIDAS DE TENDENCIA CENTRAL

1.1 DATOS NO AGRUPADOS

PYTHON

import statistics as stats
import numpy as np

# Datos de ejemplo
datos = [15, 20, 25, 30, 35, 40, 45, 50, 55, 60]

# Media
media = stats.mean(datos)  # o np.mean(datos)
print(f"Media: {media}")

# Mediana
mediana = stats.median(datos)  # o np.median(datos)
print(f"Mediana: {mediana}")

# Moda
moda = stats.mode(datos)
print(f"Moda: {moda}")

# Mínimo y Máximo
minimo = min(datos)  # o np.min(datos)
maximo = max(datos)  # o np.max(datos)
print(f"Mínimo: {minimo}, Máximo: {maximo}")

R

# Datos de ejemplo
datos <- c(15, 20, 25, 30, 35, 40, 45, 50, 55, 60)

# Media
media <- mean(datos)
print(paste("Media:", media))
[1] "Media: 37.5"
# Mediana
mediana <- median(datos)
print(paste("Mediana:", mediana))
[1] "Mediana: 37.5"
# Moda (función personalizada)
getmode <- function(v) {
  uniqv <- unique(v)
  uniqv[which.max(tabulate(match(v, uniqv)))]
}
moda <- getmode(datos)
print(paste("Moda:", moda))
[1] "Moda: 15"
# Mínimo y Máximo
minimo <- min(datos)
maximo <- max(datos)
print(paste("Mínimo:", minimo, "Máximo:", maximo))
[1] "Mínimo: 15 Máximo: 60"

1.2 DATOS AGRUPADOS

PYTHON

import pandas as pd
import numpy as np

# Datos agrupados: Intervalos y frecuencias
intervalos = ['0-10', '10-20', '20-30', '30-40', '40-50']
frecuencias = [5, 12, 20, 15, 8]

# Calcular puntos medios
puntos_medios = []
for intervalo in intervalos:
    li, ls = map(float, intervalo.split('-'))
    puntos_medios.append((li + ls) / 2)

# Media para datos agrupados
media_agrupada = sum(f * pm for f, pm in zip(frecuencias, puntos_medios)) / sum(frecuencias)
print(f"Media (datos agrupados): {media_agrupada}")

# Mediana para datos agrupados usando statistics
from statistics import median_grouped

# Crear datos expandidos
datos_expandidos = []
for pm, f in zip(puntos_medios, frecuencias):
    datos_expandidos.extend([pm] * f)

mediana_agrupada = median_grouped(datos_expandidos, interval=10)
print(f"Mediana (datos agrupados): {mediana_agrupada}")

# Moda para datos agrupados (clase modal)
clase_modal_idx = frecuencias.index(max(frecuencias))
print(f"Clase modal: {intervalos[clase_modal_idx]}")

R

# Datos agrupados
intervalos <- c("0-10", "10-20", "20-30", "30-40", "40-50")
frecuencias <- c(5, 12, 20, 15, 8)

# Calcular puntos medios
puntos_medios <- c(5, 15, 25, 35, 45)

# Media para datos agrupados
media_agrupada <- sum(frecuencias * puntos_medios) / sum(frecuencias)
print(paste("Media (datos agrupados):", media_agrupada))
[1] "Media (datos agrupados): 26.5"
# Función para mediana de datos agrupados
mediana_agrupada <- function(intervalos, frecuencias) {
  # Implementar fórmula de mediana para datos agrupados
  n <- sum(frecuencias)
  pos_mediana <- n / 2
  
  # Encontrar clase mediana
  f_acumulada <- cumsum(frecuencias)
  clase_mediana <- which(f_acumulada >= pos_mediana)[1]
  
  # Extraer límites de la clase mediana
  lim_inf <- as.numeric(unlist(strsplit(intervalos[clase_mediana], "-")))[1]
  lim_sup <- as.numeric(unlist(strsplit(intervalos[clase_mediana], "-")))[2]
  ancho <- lim_sup - lim_inf
  
  f_anterior <- ifelse(clase_mediana == 1, 0, f_acumulada[clase_mediana - 1])
  f_clase <- frecuencias[clase_mediana]
  
  mediana <- lim_inf + ancho * ((pos_mediana - f_anterior) / f_clase)
  return(mediana)
}

mediana_calc <- mediana_agrupada(intervalos, frecuencias)
print(paste("Mediana (datos agrupados):", mediana_calc))
[1] "Mediana (datos agrupados): 26.5"
# Clase modal
clase_modal <- intervalos[which.max(frecuencias)]
print(paste("Clase modal:", clase_modal))
[1] "Clase modal: 20-30"

📈 2. MEDIDAS DE DISPERSIÓN

2.1 DATOS NO AGRUPADOS

PYTHON

# Varianza (muestral y poblacional)
varianza_muestral = stats.variance(datos)  # n-1
varianza_poblacional = stats.pvariance(datos)  # n
print(f"Varianza muestral: {varianza_muestral}")
print(f"Varianza poblacional: {varianza_poblacional}")

# Desviación típica
desv_muestral = stats.stdev(datos)  # n-1
desv_poblacional = stats.pstdev(datos)  # n
print(f"Desviación típica muestral: {desv_muestral}")
print(f"Desviación típica poblacional: {desv_poblacional}")

# Coeficiente de variación
cv = (desv_muestral / media) * 100
print(f"Coeficiente de variación: {cv}%")

R

# Varianza y desviación típica
varianza <- var(datos)  # Muestral (n-1)
desviacion <- sd(datos)  # Muestral (n-1)
print(paste("Varianza muestral:", varianza))
[1] "Varianza muestral: 229.166666666667"
print(paste("Desviación típica:", desviacion))
[1] "Desviación típica: 15.1382517704875"
# Para población (n)
varianza_poblacional <- var(datos) * (length(datos) - 1) / length(datos)
desviacion_poblacional <- sqrt(varianza_poblacional)
print(paste("Varianza poblacional:", varianza_poblacional))
[1] "Varianza poblacional: 206.25"
print(paste("Desviación típica poblacional:", desviacion_poblacional))
[1] "Desviación típica poblacional: 14.3614066163451"
# Coeficiente de variación
cv <- (desviacion / mean(datos)) * 100
print(paste("Coeficiente de variación:", cv, "%"))
[1] "Coeficiente de variación: 40.3686713879666 %"

2.2 DATOS AGRUPADOS

PYTHON

# Varianza para datos agrupados
def varianza_agrupada(frecuencias, puntos_medios, media):
    n = sum(frecuencias)
    suma_cuadrados = sum(f * (pm - media)**2 for f, pm in zip(frecuencias, puntos_medios))
    return suma_cuadrados / (n - 1)  # Muestral

varianza_grp = varianza_agrupada(frecuencias, puntos_medios, media_agrupada)
desviacion_grp = np.sqrt(varianza_grp)
cv_grp = (desviacion_grp / media_agrupada) * 100

print(f"Varianza (datos agrupados): {varianza_grp}")
print(f"Desviación típica (datos agrupados): {desviacion_grp}")
print(f"Coeficiente de variación (datos agrupados): {cv_grp}%")

R

# Varianza para datos agrupados
varianza_agrupada <- function(frecuencias, puntos_medios, media) {
  n <- sum(frecuencias)
  suma_cuadrados <- sum(frecuencias * (puntos_medios - media)^2)
  return(suma_cuadrados / (n - 1))  # Muestral
}

varianza_grp <- varianza_agrupada(frecuencias, puntos_medios, media_agrupada)
desviacion_grp <- sqrt(varianza_grp)
cv_grp <- (desviacion_grp / media_agrupada) * 100

print(paste("Varianza (datos agrupados):", varianza_grp))
[1] "Varianza (datos agrupados): 131.610169491525"
print(paste("Desviación típica (datos agrupados):", desviacion_grp))
[1] "Desviación típica (datos agrupados): 11.472147553598"
print(paste("Coeficiente de variación (datos agrupados):", cv_grp, "%"))
[1] "Coeficiente de variación (datos agrupados): 43.2911228437662 %"

📊 3. CUARTILES, DECILES Y PERCENTILES

3.1 DATOS NO AGRUPADOS

PYTHON

# Cuartiles
q1 = np.percentile(datos, 25)  # Primer cuartil
q2 = np.percentile(datos, 50)  # Segundo cuartil (mediana)
q3 = np.percentile(datos, 75)  # Tercer cuartil
print(f"Cuartiles: Q1={q1}, Q2={q2}, Q3={q3}")

# Deciles
deciles = [np.percentile(datos, i*10) for i in range(1, 10)]
print(f"Deciles: {deciles}")

# Percentiles específicos
percentiles = np.percentile(datos, [10, 25, 50, 75, 90])
print(f"Percentiles 10, 25, 50, 75, 90: {percentiles}")

# Usando statistics.quantiles
cuartiles_stats = stats.quantiles(datos, n=4)
deciles_stats = stats.quantiles(datos, n=10)
print(f"Cuartiles (statistics): {cuartiles_stats}")
print(f"Deciles (statistics): {deciles_stats}")

R

# Cuartiles
cuartiles <- quantile(datos, c(0.25, 0.5, 0.75))
print(paste("Cuartiles:", paste(cuartiles, collapse=", ")))
[1] "Cuartiles: 26.25, 37.5, 48.75"
# Deciles
deciles <- quantile(datos, seq(0.1, 0.9, 0.1))
print(paste("Deciles:", paste(deciles, collapse=", ")))
[1] "Deciles: 19.5, 24, 28.5, 33, 37.5, 42, 46.5, 51, 55.5"
# Percentiles específicos
percentiles <- quantile(datos, c(0.1, 0.25, 0.5, 0.75, 0.9))
print(paste("Percentiles:", paste(percentiles, collapse=", ")))
[1] "Percentiles: 19.5, 26.25, 37.5, 48.75, 55.5"
# Rango intercuartílico
iqr <- IQR(datos)
print(paste("Rango intercuartílico:", iqr))
[1] "Rango intercuartílico: 22.5"

3.2 DATOS AGRUPADOS

PYTHON

# Para datos agrupados, usar percentiles con datos expandidos
percentiles_grp = np.percentile(datos_expandidos, [10, 25, 50, 75, 90])
print(f"Percentiles (datos agrupados): {percentiles_grp}")

# O usando la mediana agrupada para percentiles específicos
def percentil_agrupado(datos_expandidos, percentil):
    return np.percentile(datos_expandidos, percentil)

p25 = percentil_agrupado(datos_expandidos, 25)
p75 = percentil_agrupado(datos_expandidos, 75)
print(f"P25: {p25}, P75: {p75}")

R

# Expandir datos agrupados para cálculo de percentiles
datos_expandidos <- rep(puntos_medios, frecuencias)

# Calcular percentiles
percentiles_grp <- quantile(datos_expandidos, c(0.1, 0.25, 0.5, 0.75, 0.9))
print(paste("Percentiles (datos agrupados):", paste(percentiles_grp, collapse=", ")))
[1] "Percentiles (datos agrupados): 15, 15, 25, 35, 45"
# Rango intercuartílico
iqr_grp <- IQR(datos_expandidos)
print(paste("Rango intercuartílico (datos agrupados):", iqr_grp))
[1] "Rango intercuartílico (datos agrupados): 20"

📋 RESUMEN DE FUNCIONES CLAVE

PYTHON

Medida Función Librería
Media mean(), np.mean() statistics, numpy
Mediana median(), np.median() statistics, numpy
Moda mode() statistics
Varianza variance(), pvariance() statistics
Desv. Típica stdev(), pstdev() statistics
Cuartiles quantiles(datos, n=4) statistics
Percentiles np.percentile() numpy

R

Medida Función
Media mean()
Mediana median()
Moda Función personalizada
Varianza var()
Desv. Típica sd()
Cuartiles quantile()
Percentiles quantile()
Rango IQR IQR()

🎯 CONSEJOS Y RECOMENDACIONES

  1. Para datos no agrupados: Usar funciones integradas de statistics (Python) o funciones base de R
  2. Para datos agrupados: Expandir datos o usar fórmulas matemáticas específicas
  3. Manejo de NA: En R usar na.rm=TRUE, en Python limpiar datos antes
  4. Visualización: Usar matplotlib/seaborn (Python) o ggplot2 (R) para gráficos
  5. Eficiencia: Para grandes datasets, usar numpy (Python) o data.table (R)

📚 EJEMPLO COMPLETO INTEGRADO

PYTHON - Análisis Completo

import pandas as pd
import numpy as np
import statistics as stats
import matplotlib.pyplot as plt

def analisis_completo_python(datos, tipo="no_agrupado"):
    """Análisis estadístico completo en Python"""
    
    print("=== ANÁLISIS ESTADÍSTICO COMPLETO ===")
    
    if tipo == "no_agrupado":
        # Datos no agrupados
        media = stats.mean(datos)
        mediana = stats.median(datos)
        moda = stats.mode(datos)
        varianza = stats.variance(datos)
        desviacion = stats.stdev(datos)
        cv = (desviacion / media) * 100
        cuartiles = stats.quantiles(datos, n=4)
        
        print(f"Media: {media:.2f}")
        print(f"Mediana: {mediana:.2f}")
        print(f"Moda: {moda}")
        print(f"Varianza: {varianza:.2f}")
        print(f"Desviación: {desviacion:.2f}")
        print(f"CV: {cv:.2f}%")
        print(f"Cuartiles: {cuartiles}")
        
    else:
        # Datos agrupados
        print("Análisis para datos agrupados implementado arriba")
    
    return locals()

# Uso
datos_ejemplo = [23, 25, 28, 30, 32, 35, 38, 40, 42, 45, 48, 50]
resultados = analisis_completo_python(datos_ejemplo)

R - Análisis Completo

analisis_completo_r <- function(datos, tipo = "no_agrupado") {
  print("=== ANÁLISIS ESTADÍSTICO COMPLETO ===")
  
  if (tipo == "no_agrupado") {
    # Calcular todas las medidas
    media <- mean(datos)
    mediana <- median(datos)
    moda <- getmode(datos)
    varianza <- var(datos)
    desviacion <- sd(datos)
    cv <- (desviacion / media) * 100
    cuartiles <- quantile(datos, c(0.25, 0.5, 0.75))
    
    # Crear data.frame con resultados
    resultados <- data.frame(
      Medida = c("Media", "Mediana", "Moda", "Varianza", "Desviación", "CV"),
      Valor = c(media, mediana, moda, varianza, desviacion, cv)
    )
    
    print(resultados)
    print("Cuartiles:")
    print(cuartiles)
    
    return(resultados)
  }
}

# Uso
datos_ejemplo <- c(23, 25, 28, 30, 32, 35, 38, 40, 42, 45, 48, 50)
resultados <- analisis_completo_r(datos_ejemplo)
[1] "=== ANÁLISIS ESTADÍSTICO COMPLETO ==="
      Medida     Valor
1      Media 36.333333
2    Mediana 36.500000
3       Moda 23.000000
4   Varianza 80.242424
5 Desviación  8.957814
6         CV 24.654533
[1] "Cuartiles:"
  25%   50%   75% 
29.50 36.50 42.75