Python vs R para análisis de datos: cuándo usar cada uno
Llevo años alternando entre R y Python para análisis. Esta es la decisión real, sin religión: qué uso para cada cosa y por qué. Sin defender a ninguno como ganador absoluto.
La elección entre Python y R depende de cinco preguntas prácticas antes de escribir una línea: quién va a tocar ese código después, si el análisis termina en producción, cuánta estadística pesada hay detrás, si hace falta un gráfico publicable, y si hay que integrarlo con otro sistema. R gana en EDA rápido (dplyr + ggplot2 + skimr), estadística clásica (modelos mixtos, supervivencia, GLM de familias raras) y gráficos para informe. Python gana en todo lo que vaya a producción, machine learning moderno, integración con sistemas externos y, desde que existe Polars, también en datasets grandes que antes eran terreno de R. La recomendación práctica es aprender lo suficiente del lenguaje que peor dominas para no rechazar trabajo por él.
Las guerras de R vs Python en Twitter son tediosas y normalmente las pelea gente que solo usa uno de los dos. Yo uso los dos a diario, en proyectos reales, y la decisión depende casi siempre de cinco factores que no son "cuál es mejor".
Este post es mi decisión real, no la del subreddit.
#La pregunta correcta
No es "¿Python o R?". Es:
- ¿Quién más va a leer este código? Si el siguiente que toca esto es un data engineer, Python. Si es una estadística, R.
- ¿Va a producción? Sí → Python casi siempre. No → cualquiera.
- ¿Cuánta estadística pesada hay? Mucha (modelos mixtos, GLM no triviales, supervivencia) → R sin pensar.
- ¿Necesito gráficos para publicar? Sí → R + ggplot2 + patchwork.
- ¿Hay que integrar con un sistema más grande? Sí → Python.
Si esos cinco no se contestan antes de empezar a escribir, eliges con el corazón y luego sufres.
#Lo que hace mejor R, sin debate
Exploratory Data Analysis (EDA)
dplyr + ggplot2 + skimr es difícil de batir. La densidad de información por línea de código es brutal:
library(tidyverse)
library(skimr)
ventas |>
filter(status == "completed") |>
group_by(channel, month) |>
summarise(gmv = sum(price), .groups = "drop") |>
ggplot(aes(month, gmv, color = channel)) +
geom_line(linewidth = 1) +
scale_y_continuous(labels = scales::label_comma()) +
facet_wrap(~channel, scales = "free_y") +
theme_minimal()Equivalente en Python con Pandas + matplotlib son ~20 líneas con bastante boilerplate.
Estadística clásica
R fue diseñado por estadísticos para estadísticos. Cosas que en Python necesitan tres librerías y un wrapper, en R son una línea:
- Modelos mixtos:
lme4::lmer(...)en R. En Python,statsmodelsopymer4(que es un wrapper a R). - Survival analysis:
survival::survfit(...). En Python,lifelines(decente, no equivalente). - GLM con familias raras (Tweedie, ZINB, negative binomial): R lo hace de fábrica.
- Series temporales con estacionalidad múltiple:
forecast,fable. En Python, mucho más pelea.
Gráficos publicables
ggplot2 está 5 años por delante de cualquier librería de Python para gráficos de informe. plotnine (port de ggplot a Python) es decente pero le falta el ecosistema (patchwork, ggrepel, ggdist, ggalluvial).
Para un dashboard interactivo, Python + Plotly o Streamlit gana. Para una gráfica que va a un PDF de gabinete, R.
#Lo que hace mejor Python, sin debate
Cualquier cosa que toque producción
Python tiene un ecosistema de servidores, schedulers, ORMs, queues, observabilidad, type checking, packaging. R no. Cuando un análisis tiene que vivir como un cron, un endpoint, un job de BullMQ, una Lambda: Python.
# Esto es trivial en producción
from fastapi import FastAPI
import polars as pl
app = FastAPI()
@app.get("/forecast/{event_id}")
def forecast(event_id: int):
df = pl.read_database(...)
pred = model.predict(df)
return {"event_id": event_id, "forecast": pred.tolist()}En R existen plumber y similares, pero el ecosistema no se compara.
Machine learning moderno
Todo lo serio en deep learning está en Python (PyTorch, JAX, TensorFlow, transformers). LLMs, embeddings, RAG, fine-tuning: Python.
Si tu trabajo de DS tiene como output un modelo en producción, Python sin alternativa real.
Datasets grandes (con Polars)
Históricamente R era mejor para datos en RAM (data.table vuela). Polars cambió el tablero. Para datasets > 1 GB Polars supera a data.table en muchos benchmarks. Y con scan_csv lazy, Polars trabaja sobre datasets que no caben en RAM.
Integración con otros sistemas
REST, gRPC, websockets, kafka, OAuth, JWT, AWS SDK, GCP SDK, Stripe SDK, Twilio: Python tiene libraries first-class. R va años por detrás.
#Mi decisión real, en una tabla
| Tarea | Mi elección | Por qué |
|---|---|---|
| Abrir un CSV nuevo y entender qué hay | R | skim() + dplyr son insuperables para EDA rápido |
| Limpiar y agregar datos > 1 GB | Python (Polars) | Velocidad y RAM |
| Modelo estadístico con efectos mixtos | R | lme4, sin discusión |
| Forecasting de ventas para un cron diario | Python | Tiene que vivir en producción |
| Gráficas para una presentación al CEO | R + ggplot2 | Estética + densidad por línea |
| Pipeline ETL Postgres → reporting | Python | SQLAlchemy / Polars / Airflow |
| Chatbot que llama a la API de Claude | Python | El SDK oficial y los wrappers están aquí |
| Análisis ad-hoc para un email a un cliente | R | Más rápido tipear, output más limpio |
| Dashboard web interactivo | Python + Plotly Dash o Next.js + recharts | Streaming, autenticación, multi-user |
#El consejo que no quieres oír
Aprende los dos. No "domina los dos". Aprende lo suficiente del que peor te llevas para no rechazar trabajos por ello.
Si vienes de Python, dedica un fin de semana a dplyr + ggplot2. Vas a tocar techo en una semana y vas a ahorrar horas en EDA el resto de tu carrera.
Si vienes de R, dedica un par de semanas a Polars + FastAPI. Vas a entender por qué tus análisis nunca llegan a producción.
La mejor herramienta es la que conoces. Si llevas 8 años haciendo R y te pasan a Python por moda, vas a tardar 6 meses en ser productivo otra vez. Si lo que te pide la empresa lo puedes hacer en R, hazlo en R. La estadística no caduca.
#Lo que no recomiendo
- Tidyverse en Python con
siubaodplython. Buena intención, ecosistema muerto. Aprende Pandas/Polars en su propio API. - R en producción para servir tráfico de usuarios.
plumberfunciona, pero el ecosistema de monitorización/escalado no acompaña. Vas a pelear con cada despliegue. - Jupyter notebooks como código de producción. Da igual el lenguaje. Refactoriza a módulos
.pyo.Rcon tests antes de poner nada en un cron.
En el siguiente post hablo de migrar análisis financieros reales de Excel a R, paso a paso. Que es donde la mayoría de equipos se quedan estancados.
Preguntas frecuentes
¿Qué hago si el equipo era todo R y se incorpora un data engineer que solo sabe Python a mitad de proyecto?
Ese es el momento de decidir explícitamente si migrar o mantener dos lenguajes, no de dejar que ocurra solo. Si el análisis va camino de producción, suele compensar reescribir la parte final en Python y dejar R solo para la exploración inicial; si sigue siendo un análisis puntual, es más barato que el data engineer aprenda lo justo de R que reescribir un proyecto que ya funciona.
¿Julia no resuelve ya este dilema entre velocidad en producción y expresividad estadística?
En el papel promete las dos cosas, pero en la práctica su ecosistema sigue siendo mucho más pequeño que el de Python o R: menos librerías de terceros, menos gente disponible si necesitas contratar, y menos integraciones ya hechas con lo que sea que uses en producción. Vale la pena vigilarlo; hoy todavía pesa más la falta de madurez que la promesa.
Uso reticulate (o rpy2 al revés) para llamar a un lenguaje desde el otro: ¿elimina la necesidad de decidir?
Reduce el coste de mezclar los dos lenguajes, pero la decisión de arquitectura sigue haciendo falta: cada llamada cruzada paga una penalización de rendimiento por la conversión de tipos entre los dos entornos, y depurar un error que cruza el puente es más lento que depurar código nativo. Funciona bien para un caso puntual — una función estadística de R dentro de un pipeline Python —, mal como arquitectura permanente de un proyecto grande.
Seguir leyendo
Análisis exploratorio en R: del CSV al insight en 50 líneas
Una pasada real por el flow que uso para destripar un CSV nuevo sin saber qué hay dentro: lectura, perfilado, limpieza, agrupación y primeras gráficas. Todo en un script de R que cabe en una pantalla.
De Excel a R: migrando análisis financieros reales
Sustituir un Excel financiero de 30 pestañas que tarda 8 minutos en abrir por un script de R que tarda 2 segundos. Pasos reales, problemas reales, y los argumentos para convencer al financiero de que merece la pena.
Pandas + Polars: cuando tu DataFrame ya no cabe en RAM
El día que abrí un CSV de 8 millones de filas en Pandas y mi portátil cayó. Cómo Polars me lo agregó en 1,8 segundos sin tocar la RAM, y por qué no uso solo Polars.