La siguiente base de datos recoge información sobre 69 marcas de cerveza distribuidas en la ciudad, con el fin de clasificar los productos y realizar un análisis descriptivo que apoye al director de investigación en la validación de algunas hipótesis sobre el mercado.
Las variables registradas son:
library(readr)
library(dplyr)
library(ggplot2)
library(knitr)
beer <- read_csv("beer.csv", show_col_types = FALSE,
locale = locale(decimal_mark = ",", grouping_mark = "."))
# Convertimos tipo y origen en factores con etiquetas, para las tablas
beer <- beer %>%
mutate(
tipo_lab = factor(tipo,
levels = 1:5,
labels = c("Lager artesanal", "Clara artesanal",
"Lager importada", "Normal y helada",
"Baja en calorías / sin alcohol")),
origen_lab = factor(origen,
levels = c(0, 1),
labels = c("Nacional", "Importada"))
)
glimpse(beer)
## Rows: 69
## Columns: 8
## $ marca <chr> "m1", "m2", "m3", "m4", "m5", "m6", "m7", "m8", "m9", "m10"…
## $ precio <dbl> 6.24, 4.79, 5.96, 4.70, 4.11, 3.85, 2.52, 5.46, 6.00, 3.71,…
## $ calorias <dbl> 159, 160, 160, 162, 157, 151, 155, 135, 162, 142, 146, 148,…
## $ poralcoh <dbl> 5.2, 5.0, 4.9, 4.9, 5.5, 4.9, 4.7, 5.1, 5.4, 4.8, 4.4, 4.3,…
## $ tipo <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,…
## $ origen <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
## $ tipo_lab <fct> Lager artesanal, Lager artesanal, Lager artesanal, Lager ar…
## $ origen_lab <fct> Importada, Importada, Importada, Importada, Importada, Impo…
tabla_tipo <- beer %>%
count(tipo_lab, name = "Frecuencia") %>%
mutate(
`Frecuencia relativa` = round(Frecuencia / sum(Frecuencia), 3),
`Porcentaje (%)` = round(100 * Frecuencia / sum(Frecuencia), 1)
)
kable(tabla_tipo, col.names = c("Tipo de cerveza", "Frecuencia",
"Frecuencia relativa", "Porcentaje (%)"))
| Tipo de cerveza | Frecuencia | Frecuencia relativa | Porcentaje (%) |
|---|---|---|---|
| Lager artesanal | 13 | 0.188 | 18.8 |
| Clara artesanal | 17 | 0.246 | 24.6 |
| Lager importada | 10 | 0.145 | 14.5 |
| Normal y helada | 16 | 0.232 | 23.2 |
| Baja en calorías / sin alcohol | 13 | 0.188 | 18.8 |
ggplot(beer, aes(x = tipo_lab)) +
geom_bar(fill = "#c0392b") +
labs(title = "Distribución de marcas por tipo de cerveza",
x = "Tipo", y = "Número de marcas") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 25, hjust = 1))
tabla_origen <- beer %>%
count(origen_lab, name = "Frecuencia") %>%
mutate(
`Frecuencia relativa` = round(Frecuencia / sum(Frecuencia), 3),
`Porcentaje (%)` = round(100 * Frecuencia / sum(Frecuencia), 1)
)
kable(tabla_origen, col.names = c("Origen", "Frecuencia",
"Frecuencia relativa", "Porcentaje (%)"))
| Origen | Frecuencia | Frecuencia relativa | Porcentaje (%) |
|---|---|---|---|
| Nacional | 15 | 0.217 | 21.7 |
| Importada | 54 | 0.783 | 78.3 |
ggplot(beer, aes(x = origen_lab, fill = origen_lab)) +
geom_bar() +
scale_fill_manual(values = c("Nacional" = "#2980b9", "Importada" = "#f39c12")) +
labs(title = "Distribución de marcas por origen", x = "Origen", y = "Número de marcas") +
theme_minimal() +
theme(legend.position = "none")
# Función auxiliar para calcular la moda de un vector numérico continuo
# (valor más frecuente; si todos son distintos, se reporta el primero)
moda <- function(x) {
ux <- unique(x)
ux[which.max(tabulate(match(x, ux)))]
}
resumen_var <- function(x, nombre) {
data.frame(
Variable = nombre,
Media = round(mean(x), 2),
Mediana = round(median(x), 2),
Moda = round(moda(x), 2),
`Desv. estándar` = round(sd(x), 2),
`Coef. variación (%)` = round(100 * sd(x) / mean(x), 2),
Mínimo = round(min(x), 2),
Q1 = round(quantile(x, 0.25), 2),
Q3 = round(quantile(x, 0.75), 2),
Máximo = round(max(x), 2),
check.names = FALSE
)
}
tabla_resumen <- bind_rows(
resumen_var(beer$precio, "Precio (USD)"),
resumen_var(beer$calorias, "Calorías"),
resumen_var(beer$poralcoh, "% Alcohol")
)
kable(tabla_resumen, row.names = FALSE)
| Variable | Media | Mediana | Moda | Desv. estándar | Coef. variación (%) | Mínimo | Q1 | Q3 | Máximo |
|---|---|---|---|---|---|---|---|---|---|
| Precio (USD) | 4.96 | 4.79 | 4.02 | 1.45 | 29.14 | 2.36 | 3.9 | 6.24 | 7.8 |
| Calorías | 142.35 | 148.00 | 148.00 | 29.90 | 21.01 | 58.00 | 142.0 | 160.00 | 201.0 |
| % Alcohol | 4.42 | 4.90 | 5.00 | 1.57 | 35.63 | 0.00 | 4.4 | 5.10 | 6.0 |
detectar_atipicos <- function(x, nombre) {
q1 <- quantile(x, 0.25)
q3 <- quantile(x, 0.75)
ric <- q3 - q1
li <- q1 - 1.5 * ric
ls <- q3 + 1.5 * ric
atipicos <- x[x < li | x > ls]
data.frame(
Variable = nombre,
`Límite inferior` = round(li, 2),
`Límite superior` = round(ls, 2),
`N° atípicos` = length(atipicos),
check.names = FALSE
)
}
tabla_atipicos <- bind_rows(
detectar_atipicos(beer$precio, "Precio"),
detectar_atipicos(beer$calorias, "Calorías"),
detectar_atipicos(beer$poralcoh, "% Alcohol")
)
kable(tabla_atipicos, row.names = FALSE)
| Variable | Límite inferior | Límite superior | N° atípicos |
|---|---|---|---|
| Precio | 0.39 | 9.75 | 0 |
| Calorías | 115.00 | 187.00 | 13 |
| % Alcohol | 3.35 | 6.15 | 7 |
library(patchwork)
h1 <- ggplot(beer, aes(x = precio)) +
geom_histogram(bins = 10, fill = "#16a085", color = "white") +
labs(title = "Precio", x = "Precio (USD)", y = "Frecuencia") + theme_minimal()
h2 <- ggplot(beer, aes(x = calorias)) +
geom_histogram(bins = 10, fill = "#8e44ad", color = "white") +
labs(title = "Calorías", x = "Calorías", y = "Frecuencia") + theme_minimal()
h3 <- ggplot(beer, aes(x = poralcoh)) +
geom_histogram(bins = 10, fill = "#d35400", color = "white") +
labs(title = "% Alcohol", x = "% Alcohol", y = "Frecuencia") + theme_minimal()
h1 + h2 + h3
b1 <- ggplot(beer, aes(y = precio)) +
geom_boxplot(fill = "#16a085") + labs(title = "Precio") + theme_minimal()
b2 <- ggplot(beer, aes(y = calorias)) +
geom_boxplot(fill = "#8e44ad") + labs(title = "Calorías") + theme_minimal()
b3 <- ggplot(beer, aes(y = poralcoh)) +
geom_boxplot(fill = "#d35400") + labs(title = "% Alcohol") + theme_minimal()
b1 + b2 + b3
p1 <- ggplot(beer, aes(x = origen_lab, y = precio, fill = origen_lab)) +
geom_boxplot() + labs(title = "Precio según origen", x = "", y = "Precio (USD)") +
theme_minimal() + theme(legend.position = "none")
p2 <- ggplot(beer, aes(x = origen_lab, y = calorias, fill = origen_lab)) +
geom_boxplot() + labs(title = "Calorías según origen", x = "", y = "Calorías") +
theme_minimal() + theme(legend.position = "none")
p1 + p2
Nota: esta sección es la que más pesa en la evaluación. Aquí dejo un borrador con los hallazgos numéricos ya verificados sobre tu propia base; léelo, compáralo con lo que te muestra tu Knit, y ajústalo con tus propias palabras y cualquier observación adicional que veas en tus gráficos.
Conclusión general (para completar): con base en lo anterior, el mercado de cervezas analizado está dominado por marcas importadas, con precios y contenido de alcohol más dispersos que el contenido calórico. Esto podría orientarse hacia recomendaciones sobre segmentación de producto o estrategia de precios — desarrolla aquí tu propia interpretación de negocio.