---
title: "Análisis de Series de Tiempo"
subtitle: "Unidades defectuosas por turno de producción: tendencia, estacionariedad y autocorrelación"
author:
- "Juliana Otero Rico"
-
date: today
lang: es
format:
html:
embed-resources: true
toc: true
toc-depth: 3
toc-title: "Contenido"
theme: cosmo
code-fold: show
code-summary: "Ver código R"
code-tools: true
highlight-style: github
number-sections: true
fig-align: center
smooth-scroll: true
execute:
echo: true
warning: false
message: false
---
```{r}
#| label: setup
#| include: false
pkgs <- c("tseries", "forecast", "ggplot2", "knitr", "kableExtra", "dplyr")
for (p in pkgs) if (!require(p, character.only = TRUE, quietly = TRUE))
install.packages(p)
library(tseries)
library(forecast)
library(ggplot2)
library(knitr)
library(kableExtra)
library(dplyr)
alpha <- 0.05 # nivel de significancia global
```
# Introducción {.unnumbered}
En todo proceso productivo, la calidad del producto depende de las
condiciones en las que se inicia cada turno de trabajo. Cuando los datos se
registran de forma secuencial (turno tras turno), el **orden** de las
observaciones importa: lo que ocurre en un turno suele estar relacionado con lo
que ocurrió en los anteriores. Las **series de tiempo** son la herramienta
estadística que permite estudiar esa dependencia temporal.
Este informe analiza el número de **unidades defectuosas** producidas en
**18 turnos consecutivos**, junto con el **tiempo de preparación** de cada
turno. Antes de construir cualquier modelo de pronóstico es indispensable
conocer tres propiedades de la serie: su **tendencia**, su
**estacionalidad** y su **estacionariedad**, pues de ellas depende qué
técnicas pueden aplicarse correctamente.
## Objetivo general {.unnumbered}
Caracterizar el comportamiento temporal de las unidades defectuosas por turno
y determinar si la serie es estacionaria, mediante análisis gráfico, pruebas
de hipótesis y análisis de autocorrelación, utilizando el lenguaje **R**.
## Objetivos específicos {.unnumbered}
1. Describir la serie y representarla gráficamente, identificando su
**tendencia**, **estacionalidad** y **estacionariedad** de forma visual.
2. Evaluar la estacionariedad con tres pruebas formales (**ADF**, **KPSS** y
**Phillips-Perron**) y, si no es estacionaria, aplicar **diferenciación**
hasta lograrla.
3. Analizar la **autocorrelación** de la serie mediante la función de
autocorrelación (**ACF**) e interpretar su estructura de dependencia.
## Metodología {.unnumbered}
| Etapa | Herramienta | Propósito |
|:--|:--|:--|
| Exploración | Gráfico de la serie, estadísticos descriptivos, regresión lineal | Identificar tendencia y estacionalidad |
| Inferencia | Pruebas ADF, KPSS y PP ($\alpha = 0.05$) | Contrastar formalmente la estacionariedad |
| Transformación | Diferenciación de orden $d$ | Estabilizar la media de la serie |
| Dependencia | Función de autocorrelación (ACF) | Medir la relación entre observaciones separadas $k$ turnos |
: **Tabla 1.** Resumen de la metodología empleada. {.striped .hover}
---
# Datos del problema
Se dispone de **18 turnos** de producción con dos variables:
*Tiempo de preparación* (minutos) y *Unidades defectuosas* (conteo). La serie
de interés es el número de unidades defectuosas, $Y_t$.
```{r}
#| label: datos
turno <- 1:18
tiempo_prep <- c(20, 22, 24, 25, 27, 28, 30, 32, 34, 35,
37, 39, 40, 42, 44, 46, 48, 50)
unidades_def <- c(28, 25, 24, 23, 21, 20, 19, 18, 17, 16,
15, 14, 13, 12, 12, 10, 10, 9)
# Objeto de serie de tiempo (frecuencia = 1 observación por turno)
ts_Y <- ts(unidades_def, start = 1, frequency = 1)
data.frame(Turno = turno,
`Tiempo Prep.` = tiempo_prep,
`Unid. Defect.` = unidades_def,
check.names = FALSE) |>
kable(caption = "Tabla 2. Datos originales del problema.",
align = "ccc") |>
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center")
```
---
# Descripción de la serie de tiempo {#sec-item1}
## Definición y modelo de descomposición
Una **serie de tiempo** $\{Y_t\}_{t=1}^{T}$ es una secuencia de observaciones
registradas en intervalos regulares. En este caso:
$$Y_t = \text{unidades defectuosas en el turno } t, \qquad t = 1, 2, \ldots, 18.$$
Se asume una descomposición **aditiva**:
$$\boxed{Y_t \;=\; T_t + S_t + \varepsilon_t}$$
| Componente | Nombre | Qué representa |
|:---:|:---|:---|
| $T_t$ | **Tendencia** | Movimiento sistemático de largo plazo (sube o baja) |
| $S_t$ | **Estacionalidad** | Patrón que se repite cada $s$ períodos |
| $\varepsilon_t$ | **Residuo** | Variación aleatoria no explicada |
: **Tabla 3.** Componentes de una serie de tiempo. {.striped .hover}
## Gráfico de la serie
```{r}
#| label: fig-serie
#| fig-cap: "**Figura 1.** Unidades defectuosas por turno. La línea roja discontinua es la tendencia lineal ajustada por MCO (con banda de confianza del 95 %)."
#| fig-width: 8
#| fig-height: 4.5
df <- data.frame(t = turno, Y = unidades_def)
ggplot(df, aes(x = t, y = Y)) +
geom_line(color = "#1565C0", linewidth = 1.2) +
geom_point(color = "#0D47A1", size = 3.5) +
geom_smooth(method = "lm", formula = y ~ x, se = TRUE,
color = "#C62828", linetype = "dashed",
linewidth = 0.9, alpha = 0.12) +
scale_x_continuous(breaks = 1:18) +
labs(title = expression("Serie de tiempo: unidades defectuosas " ~ Y[t]),
x = "Turno ( t )", y = expression(Y[t])) +
theme_bw(base_size = 13) +
theme(plot.title = element_text(hjust = 0.5, face = "bold"),
panel.grid.minor = element_blank())
```
```{r}
#| label: calculos-previos
#| include: false
mod <- lm(Y ~ t, data = df)
s <- summary(mod)
b0 <- unname(coef(mod)[1]); b1 <- unname(coef(mod)[2])
r2 <- s$r.squared
p_b1 <- s$coefficients[2, 4]
rho_xy <- cor(tiempo_prep, unidades_def)
cv <- sd(unidades_def) / mean(unidades_def) * 100
```
::: {.callout-note title="Interpretación del gráfico"}
- **Tendencia:** la serie desciende de forma sostenida, de
**`r unidades_def[1]`** defectuosas en el turno 1 a
**`r unidades_def[18]`** en el turno 18. Las unidades defectuosas
disminuyen en promedio unas **`r round(abs(b1), 2)` por turno**.
- **Estacionalidad:** no se observan ciclos ni oscilaciones que se repitan;
la curva baja de manera casi continua.
- **Estacionariedad:** la serie **no oscila alrededor de un nivel fijo**: su
media cambia con el tiempo, por lo que, a simple vista, **no es
estacionaria**.
:::
## Estadísticos descriptivos
```{r}
#| label: tbl-stats
data.frame(
Estadístico = c("$n$ (observaciones)", "$\\bar{Y}$ (media)",
"$\\widetilde{Y}$ (mediana)", "$s$ (desv. estándar)",
"$\\min(Y_t)$", "$\\max(Y_t)$", "Rango", "CV (%)"),
Valor = c(length(unidades_def),
round(mean(unidades_def), 2),
round(median(unidades_def), 2),
round(sd(unidades_def), 2),
min(unidades_def), max(unidades_def),
diff(range(unidades_def)),
round(cv, 2))
) |>
kable(caption = "Tabla 4. Estadísticos descriptivos de $Y_t$.",
escape = FALSE, align = "lr") |>
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center")
```
::: {.callout-note title="Interpretación de la tabla"}
En promedio hubo **`r round(mean(unidades_def), 1)`** unidades defectuosas por
turno (mediana `r median(unidades_def)`). Los valores van de
`r min(unidades_def)` a `r max(unidades_def)`, un rango de
`r diff(range(unidades_def))` unidades. El coeficiente de variación
(**`r round(cv, 1)` %**) indica una variabilidad considerable alrededor de la
media. Esa dispersión **no es aleatoria**: proviene en gran parte de la
tendencia decreciente.
:::
## Componente de tendencia
Se ajusta una recta de tendencia por mínimos cuadrados ordinarios (MCO):
$$\hat{Y}_t = \hat{\beta}_0 + \hat{\beta}_1\, t$$
```{r}
#| label: tendencia
as.data.frame(s$coefficients) |>
tibble::rownames_to_column("Parámetro") |>
mutate(Parámetro = c("$\\hat{\\beta}_0$ (intercepto)",
"$\\hat{\\beta}_1$ (pendiente)")) |>
kable(digits = 4,
escape = FALSE,
col.names = c("Parámetro", "Estimado", "Error est.", "$t$", "$p$-valor"),
caption = paste0("Tabla 5. Regresión de tendencia lineal. ",
"$R^2 = ", round(s$r.squared, 4),
"$; $R^2_{\\text{aj}} = ",
round(s$adj.r.squared, 4), "$.")) |>
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center")
```
::: {.callout-note title="Interpretación de la tabla"}
La recta estimada es $\hat{Y}_t = `r round(b0, 2)` `r round(b1, 2)`\, t$.
- **Pendiente:** por cada turno adicional, las unidades defectuosas bajan en
promedio **`r round(abs(b1), 2)`**. Es estadísticamente significativa
($p < 0.001$), así que existe una **tendencia decreciente real**.
- **Ajuste:** $R^2 = `r round(r2, 3)`$, es decir, el tiempo (el número de
turno) explica cerca del **`r round(r2 * 100, 1)` %** de la variación de la
serie.
:::
## Relación con el tiempo de preparación
```{r}
#| label: fig-tprep
#| fig-cap: "**Figura 3.** Unidades defectuosas frente al tiempo de preparación."
#| fig-width: 6
#| fig-height: 4
ggplot(data.frame(x = tiempo_prep, y = unidades_def), aes(x, y)) +
geom_point(color = "#0D47A1", size = 3.2) +
geom_smooth(method = "lm", formula = y ~ x, se = FALSE,
color = "#C62828", linetype = "dashed") +
labs(x = "Tiempo de preparación (min)", y = "Unidades defectuosas") +
theme_bw(base_size = 13)
```
La correlación entre ambas variables es $r = `r round(rho_xy, 3)`$: a mayor
tiempo de preparación, menos unidades defectuosas. Como **ambas variables
evolucionan con el tiempo** (una sube y la otra baja), esta correlación debe
tomarse con cautela: no demuestra por sí sola una relación causal.
## Componente de estacionalidad
La estacionalidad exige un período $s$ tal que $S_{t+s} = S_t$. Con $T = 18$
observaciones, un registro por turno y sin un período definido en los datos, no
es posible identificar un componente estacional formal (se necesitarían varios
ciclos completos). Además, el gráfico no muestra patrones que se repitan.
::: {.callout-important title="Conclusión sobre estacionalidad"}
La serie **no presenta estacionalidad** identificable.
:::
## Análisis visual de estacionariedad
Una serie es **débilmente estacionaria** si cumple:
$$\begin{cases}
E[Y_t] = \mu & \forall\, t \quad \text{(media constante)} \\[4pt]
\operatorname{Var}(Y_t) = \sigma^2 < \infty & \forall\, t \quad \text{(varianza constante)} \\[4pt]
\operatorname{Cov}(Y_t,\, Y_{t+k}) = \gamma(k) & \text{solo depende del rezago } k
\end{cases}$$
::: {.callout-important title="Conclusión preliminar (visual)"}
La media de $Y_t$ **no es constante** (decrece con $t$), lo que viola la
primera condición. La serie es, visualmente, **NO estacionaria**. Esto se
confirma formalmente en el Ítem 2.
:::
---
# Pruebas de estacionariedad y diferenciación {#sec-item2}
Se aplican tres pruebas complementarias. Dos de ellas parten de que la serie
**no** es estacionaria y una de que **sí** lo es; por eso se usan juntas.
| Prueba | Paquete R | $H_0$ | $H_1$ |
|:---|:---:|:---|:---|
| **ADF** (Dickey-Fuller aumentada) | `tseries` | Raíz unitaria (no estacionaria) | Estacionaria |
| **KPSS** (Kwiatkowski et al.) | `tseries` | Estacionaria | Raíz unitaria |
| **PP** (Phillips-Perron) | `tseries` | Raíz unitaria (no estacionaria) | Estacionaria |
: **Tabla 6.** Pruebas de estacionariedad utilizadas. {.striped .hover}
**Regla de decisión:** se rechaza $H_0$ si el $p$-valor $< \alpha = 0.05$.
::: {.callout-tip title="Cómo leer los resultados"}
- En **ADF** y **PP**, un $p$-valor *pequeño* indica que la serie **es**
estacionaria.
- En **KPSS** ocurre lo contrario: un $p$-valor *pequeño* indica que la serie
**no es** estacionaria.
- Una serie se considera estacionaria con confianza cuando **las tres pruebas
coinciden**.
- En R, los $p$-valores de estas pruebas se truncan: `0.01` significa
"$\leq 0.01$" y, en KPSS, `0.10` significa "$\geq 0.10$".
:::
## Ecuaciones de las pruebas
**ADF** (modelo con intercepto y tendencia):
$$\Delta Y_t = \alpha + \beta\,t + \delta Y_{t-1} + \sum_{i=1}^{p}\phi_i\,\Delta Y_{t-i} + \varepsilon_t, \qquad
H_0: \delta = 0 \;\; \text{vs} \;\; H_1: \delta < 0$$
**KPSS:**
$$\text{KPSS} = T^{-2}\sum_{t=1}^{T}\frac{\hat{S}_t^{2}}{\hat{\sigma}^{2}_{\varepsilon}}, \qquad
\hat{S}_t = \sum_{j=1}^{t}\hat{e}_j$$
**Phillips-Perron:** misma hipótesis que ADF, pero corrige la autocorrelación y
la heterocedasticidad de los errores de forma no paramétrica (Newey-West), sin
añadir rezagos.
**Diferenciación:** si la serie no es estacionaria, se restan observaciones
consecutivas:
$$\nabla Y_t = Y_t - Y_{t-1}, \qquad
\nabla^2 Y_t = \nabla Y_t - \nabla Y_{t-1} = Y_t - 2Y_{t-1} + Y_{t-2}$$
## Aplicación de las pruebas
Se define una función que aplica las tres pruebas y organiza los resultados.
En la serie original (que tiene tendencia) KPSS se contrasta con
`null = "Trend"`; en las series diferenciadas, con `null = "Level"`.
```{r}
#| label: funcion-pruebas
# Series diferenciadas
ts_d1 <- diff(ts_Y, differences = 1)
ts_d2 <- diff(ts_Y, differences = 2)
run_tests <- function(x, serie, kpss_null) {
a <- adf.test(x)
k <- kpss.test(x, null = kpss_null)
p <- pp.test(x)
data.frame(
Serie = serie,
Prueba = c("ADF", "KPSS", "PP"),
H0 = c("Raíz unitaria", "Estacionaria", "Raíz unitaria"),
Estadistico = as.numeric(c(a$statistic, k$statistic, p$statistic)),
p = c(a$p.value, k$p.value, p$p.value),
Estacionaria = c(a$p.value < alpha, k$p.value >= alpha, p$p.value < alpha)
)
}
res <- rbind(
run_tests(ts_Y, "Serie original", "Trend"),
run_tests(ts_d1, "Primera diferencia", "Level"),
run_tests(ts_d2, "Segunda diferencia", "Level")
)
# Formato del p-valor (R trunca a 0.01 / 0.10)
fmt_p <- function(p, prueba) {
if (p <= 0.01) "≤ 0.01"
else if (prueba == "KPSS" && p >= 0.10) "≥ 0.10"
else formatC(p, format = "f", digits = 4)
}
res$p_txt <- mapply(fmt_p, res$p, res$Prueba)
```
### Serie original $Y_t$
```{r}
#| label: orig-detalle
res |> filter(Serie == "Serie original") |>
transmute(Prueba, `$H_0$` = H0,
Estadístico = round(Estadistico, 4),
`$p$-valor` = p_txt,
Decisión = ifelse(Estacionaria, "Estacionaria", "No estacionaria")) |>
kable(escape = FALSE, align = "llrrl",
caption = "Tabla 7. Pruebas sobre la serie original.") |>
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center")
```
::: {.callout-note title="Interpretación"}
Las **tres pruebas coinciden**: ADF y PP no rechazan la hipótesis de raíz
unitaria ($p > 0.05$) y KPSS rechaza la hipótesis de estacionariedad
($p < 0.05$). La serie original **no es estacionaria**, lo que confirma la
conclusión visual y hace necesario **diferenciarla**.
:::
```{r}
#| label: ndiffs
cat("Número sugerido de diferencias (ndiffs):\n")
cat(" KPSS:", ndiffs(ts_Y, test = "kpss"), "\n")
cat(" ADF :", ndiffs(ts_Y, test = "adf"), "\n")
cat(" PP :", ndiffs(ts_Y, test = "pp"), "\n")
```
Los criterios de `ndiffs()` no son unánimes, por lo que se evalúan de forma
explícita la primera y la segunda diferencia.
### Primera y segunda diferencia
```{r}
#| label: fig-diff
#| fig-cap: "**Figura 4.** Series diferenciadas. Línea roja: cero; línea naranja punteada: media de la serie."
#| fig-subcap:
#| - "Primera diferencia $\\nabla Y_t$"
#| - "Segunda diferencia $\\nabla^2 Y_t$"
#| layout-ncol: 2
#| fig-width: 5.5
#| fig-height: 4
plot_dif <- function(x, t0, titulo, ylab, col1, col2) {
d <- data.frame(t = t0:18, v = as.numeric(x))
ggplot(d, aes(t, v)) +
geom_hline(yintercept = 0, linetype = "dashed", color = "#C62828") +
geom_hline(yintercept = mean(d$v), linetype = "dotted",
color = "#E65100", linewidth = 1) +
geom_line(color = col1, linewidth = 1.1) +
geom_point(color = col2, size = 3) +
scale_x_continuous(breaks = seq(t0, 18, by = 2)) +
labs(title = titulo, x = "Turno ( t )", y = ylab) +
theme_bw(base_size = 12) +
theme(plot.title = element_text(hjust = 0.5, face = "bold"),
panel.grid.minor = element_blank())
}
plot_dif(ts_d1, 2, "Primera diferencia", expression(nabla*Y[t]),
"#2E7D32", "#1B5E20")
plot_dif(ts_d2, 3, "Segunda diferencia", expression(nabla^2*Y[t]),
"#6A1B9A", "#4A148C")
```
::: {.callout-note title="Interpretación de los gráficos"}
- **Primera diferencia:** ya no hay una caída continua, pero los valores se
mantienen **casi siempre por debajo de cero** (media
`r round(mean(ts_d1), 2)`): todavía queda una tendencia residual,
consecuencia de que la caída original no era perfectamente lineal.
- **Segunda diferencia:** los valores **oscilan alrededor de cero**
(media `r round(mean(ts_d2), 2)`) con amplitud estable. Visualmente es
compatible con una serie estacionaria.
:::
## Resumen general de las pruebas
```{r}
#| label: tbl-resumen
tabla <- res |>
mutate(
Decisión = cell_spec(
ifelse(Estacionaria, "Estacionaria", "No estacionaria"),
format = "html", # <--- AÑADIDO
color = "white",
bold = TRUE,
background = ifelse(Estacionaria, "#2E7D32", "#C62828"),
escape = FALSE)
) |>
transmute(Prueba, `$H_0$` = H0,
Estadístico = round(Estadistico, 4),
`$p$-valor` = p_txt, Decisión)
kable(tabla, format = "html", escape = FALSE, align = "llrrc", # <--- AÑADIDO format = "html"
caption = paste0("Tabla 8. Resultados de las pruebas de estacionariedad ",
"($\\alpha = ", alpha, "$).")) |>
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center") |>
pack_rows("Serie original", 1, 3) |>
pack_rows("Primera diferencia (d = 1)", 4, 6) |>
pack_rows("Segunda diferencia (d = 2)", 7, 9)
```
Para facilitar la lectura, se resume cuántas pruebas consideran estacionaria a
cada serie:
```{r}
#| label: tbl-veredicto
niveles <- unique(res$Serie)
k <- sapply(split(res$Estacionaria, factor(res$Serie, levels = niveles)), sum)
veredicto <- data.frame(
Serie = niveles,
`Pruebas que indican estacionariedad` = paste(k, "de 3"),
Conclusión = ifelse(k == 3, "Estacionaria",
ifelse(k == 0, "No estacionaria", "Resultado mixto (no concluyente)")),
check.names = FALSE
)
kable(veredicto, align = "lcl",
caption = "**Tabla 9.** Veredicto por serie (consenso de las tres pruebas).") |>
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center")
```
::: {.callout-note title="Interpretación de las tablas"}
1. **Serie original:** 0 de 3 pruebas indican estacionariedad → **no
estacionaria**.
2. **Primera diferencia:** el resultado es **mixto**. Solo PP la considera
estacionaria; ADF y KPSS no. Cuando las pruebas se contradicen no hay
evidencia suficiente para afirmar estacionariedad, y el gráfico anterior
muestra una media aún distinta de cero.
3. **Segunda diferencia:** las **tres pruebas coinciden** en que es
estacionaria (ADF y PP rechazan la raíz unitaria; KPSS no rechaza la
estacionariedad).
:::
::: {.callout-important title="Conclusión del Ítem 2"}
La serie de unidades defectuosas es **integrada de orden 2**, $Y_t \sim I(2)$:
requiere **dos diferenciaciones** ($d = 2$) para ser estacionaria. La serie
estacionaria con la que se trabaja a partir de aquí es
$$\nabla^2 Y_t = Y_t - 2Y_{t-1} + Y_{t-2}, \qquad t = 3, \ldots, 18 \;\; (16 \text{ datos}).$$
*Nota:* con solo 18 observaciones, estas pruebas tienen poca potencia, así
que sus resultados deben verse como evidencia orientativa.
:::
---
# Ítem 3 — Análisis de autocorrelación (ACF) {#sec-item3}
## ¿Qué mide la ACF?
La **función de autocorrelación (ACF)** mide qué tan parecida es la serie a sí
misma cuando se desplaza $k$ turnos (rezago $k$). Responde a la pregunta:
*¿el número de defectuosas de un turno está relacionado con el de $k$ turnos
antes?*
$$r_k = \frac{\sum_{t=1}^{T-k}(Y_t - \bar{Y})(Y_{t+k} - \bar{Y})}{\sum_{t=1}^{T}(Y_t - \bar{Y})^2},
\qquad -1 \leq r_k \leq 1$$
::: {.callout-tip title="Cómo leer un gráfico ACF"}
- Cada **barra** es la autocorrelación $r_k$ en un rezago $k$.
- Las **líneas punteadas azules** son las bandas de significancia al 95 %,
$\pm 1.96/\sqrt{n}$. Una barra que **sale de la banda** indica una
autocorrelación significativamente distinta de cero.
- **Barras altas que bajan muy despacio** → la serie tiene tendencia (no es
estacionaria).
- **Barras dentro de la banda** → no hay dependencia lineal relevante entre
turnos.
:::
## ACF de la serie original y de las series diferenciadas
Se calcula la ACF de la serie original y de sus dos diferencias, para ver
cómo cambia la dependencia al diferenciar.
```{r}
#| label: acf-graficos
#| fig-cap: "**Figura 5.** Función de autocorrelación (ACF) de la serie original y de las series diferenciadas."
#| fig-subcap:
#| - "Serie original $Y_t$"
#| - "Primera diferencia $\\nabla Y_t$"
#| - "Segunda diferencia $\\nabla^2 Y_t$"
#| layout-ncol: 3
#| fig-width: 4.5
#| fig-height: 3.6
ggAcf(ts_Y, lag.max = 8) + labs(title = "Serie original", x = "Rezago (k)", y = "ACF") + theme_bw(base_size = 12)
ggAcf(ts_d1, lag.max = 8) + labs(title = "Primera diferencia", x = "Rezago (k)", y = "ACF") + theme_bw(base_size = 12)
ggAcf(ts_d2, lag.max = 8) + labs(title = "Segunda diferencia", x = "Rezago (k)", y = "ACF") + theme_bw(base_size = 12)
```
```{r}
#| label: acf-tabla
# --- Autocorrelaciones muestrales y bandas de significancia (95 %) ---
lag_max <- 8
acf_tab <- function(x, nombre) {
a <- acf(x, lag.max = lag_max, plot = FALSE)
data.frame(serie = nombre, k = 1:lag_max,
r = as.numeric(a$acf[-1]),
banda = qnorm(0.975) / sqrt(length(x)))
}
acf_df <- rbind(acf_tab(ts_Y, "Original"),
acf_tab(ts_d1, "1ª dif."),
acf_tab(ts_d2, "2ª dif."))
acf_df$sig <- abs(acf_df$r) > acf_df$banda
# --- Tabla (valores significativos en rojo y negrita) ---
tab <- data.frame(`Rezago k` = 1:6, check.names = FALSE)
for (nm in c("Original", "1ª dif.", "2ª dif.")) {
d <- subset(acf_df, serie == nm & k <= 6)
tab[[paste0("$r_k$ ", nm)]] <- cell_spec(sprintf("%.3f", d$r),
format = "html", # <--- AÑADIDO
bold = d$sig,
color = ifelse(d$sig, "#C62828", "black"),
escape = FALSE)
}
bandas <- unique(acf_df[, c("serie", "banda")])
kable(tab, format = "html", escape = FALSE, align = "cccc", # <--- AÑADIDO format = "html"
caption = paste0("Tabla 10. Autocorrelaciones muestrales. ",
"En rojo: valores fuera de la banda del 95 % ",
"(±", sprintf("%.3f", bandas$banda[1]), " original; ",
"±", sprintf("%.3f", bandas$banda[2]), " 1ª dif.; ",
"±", sprintf("%.3f", bandas$banda[3]), " 2ª dif.).")) |>
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center")
# --- Valores auxiliares para el texto ---
r_o <- acf_df$r[acf_df$serie == "Original"]
r_d1 <- acf_df$r[acf_df$serie == "1ª dif."]
r_d2 <- acf_df$r[acf_df$serie == "2ª dif."]
k_sig <- which(!acf_df$sig[acf_df$serie == "Original"])[1] - 1 # rezagos iniciales significativos
lags_sig <- function(nm) {
l <- acf_df$k[acf_df$serie == nm & acf_df$sig]
if (length(l) == 0) "ninguno" else paste(l, collapse = ", ")
}
```
```{r}
#| label: acf-resumen
data.frame(
Serie = c("Original $Y_t$", "1ª diferencia $\\nabla Y_t$", "2ª diferencia $\\nabla^2 Y_t$"),
`Rezagos significativos` = c(lags_sig("Original"), lags_sig("1ª dif."), lags_sig("2ª dif.")),
`Patrón de la ACF` = c("Decaimiento lento desde valores altos",
"Sin barras fuera de la banda",
"Una sola barra negativa (rezago 1)"),
Lectura = c("Tendencia: no estacionaria",
"Sin dependencia lineal relevante",
"Posible sobrediferenciación"),
check.names = FALSE
) |>
kable(escape = FALSE, align = "llll",
caption = "Tabla 11. Resumen de lo que muestra la ACF en cada serie.") |>
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center")
```
## Interpretación
::: {.callout-note title="1. Serie original: autocorrelación fuerte y persistente"}
La ACF **decrece lentamente**: $r_1 = `r sprintf("%.2f", r_o[1])`$,
$r_2 = `r sprintf("%.2f", r_o[2])`$ y $r_3 = `r sprintf("%.2f", r_o[3])`$,
con los primeros **`r k_sig` rezagos significativos**. En términos prácticos:
las unidades defectuosas de un turno se parecen mucho a las de los turnos
cercanos, porque todos pertenecen a la misma caída sostenida. Este es el
patrón típico de una **serie con tendencia**, y es coherente con el Ítem 2,
donde las tres pruebas indicaron que la serie original **no es estacionaria**.
:::
::: {.callout-note title="2. Primera diferencia: la dependencia casi desaparece"}
Al diferenciar una vez, **ninguna autocorrelación** sale de la banda
(rezagos significativos: `r lags_sig("1ª dif.")`); el valor más alto en
magnitud es $r_1 = `r sprintf("%.2f", r_d1[1])`$. Es decir, el cambio entre
un turno y el siguiente ya no depende de forma apreciable de los cambios
anteriores. Aun así, esta serie tiene una media negativa
(≈ `r round(mean(ts_d1), 2)` unidades por turno) y en el Ítem 2 las pruebas
ADF y KPSS no la declararon estacionaria. La ACF mide **dependencia entre
turnos**, no si la media es constante, por lo que ambas lecturas no son
contradictorias, pero tampoco permiten cerrar el tema con una sola
herramienta.
:::
::: {.callout-note title="3. Segunda diferencia: serie estacionaria con una autocorrelación en el rezago 1"}
En $\nabla^2 Y_t$ solo el **rezago 1** sale de la banda, y con signo
**negativo**: $r_1 = `r sprintf("%.2f", r_d2[1])`$ (banda
±`r sprintf("%.2f", bandas$banda[3])`). Esto significa que un aumento en el
cambio de defectuosas tiende a ser seguido por una disminución, y viceversa.
Los rezagos $k \geq 2$ **no son significativos**
(`r sprintf("%.2f", r_d2[2])`, `r sprintf("%.2f", r_d2[3])`, ...), así que no
queda dependencia de más largo plazo.
:::
::: {.callout-warning title="Una señal a vigilar: posible sobrediferenciación"}
Una autocorrelación negativa en el rezago 1, cercana a $-0.5$, es la huella
clásica de haber **diferenciado de más**: al restar de nuevo una serie que ya
era estable, se introduce artificialmente una dependencia negativa entre
valores vecinos. Aquí $r_1 = `r sprintf("%.2f", r_d2[1])`$, y la primera
diferencia ya no mostraba autocorrelación significativa. Por eso, aunque las
tres pruebas del Ítem 2 declaran estacionaria a $\nabla^2 Y_t$ (y es la serie
que se adopta), **no se puede descartar** que $d = 1$ describa bien los datos.
Con solo 18 observaciones las pruebas tienen poca potencia y es difícil zanjar
esta duda; en una etapa de modelado se compararían las dos alternativas con
criterios de información (AIC/BIC).
:::
::: {.callout-important title="Conclusión del Ítem 3"}
- La **serie original** tiene autocorrelación **positiva, alta y persistente**
(decaimiento lento): evidencia de tendencia y de no estacionariedad.
- Al **diferenciar**, la dependencia desaparece: tras una diferencia no hay
rezagos significativos y tras dos solo queda el rezago 1, con signo negativo.
- La serie estacionaria adoptada, $\nabla^2 Y_t$, **no presenta
autocorrelación de largo plazo**; la barra negativa en el rezago 1 sugiere
que $d = 2$ podría ser un poco más de lo necesario.
:::
---
# Conclusiones {.unnumbered}
1. **Descripción (Ítem 1):** las unidades defectuosas disminuyen de forma
sostenida a lo largo de los 18 turnos, en promedio unas
`r round(abs(b1), 2)` por turno, y no presentan estacionalidad
identificable. La tendencia no es exactamente lineal: la caída se
desacelera hacia el final. Por tener media cambiante, la serie original
**no es estacionaria**.
2. **Estacionariedad (Ítem 2):** las tres pruebas (ADF, KPSS y PP) confirman
que la serie original **no es estacionaria**. Tras la primera diferencia
las pruebas se contradicen (solo PP la declara estacionaria), y tras la
**segunda diferencia** las tres coinciden en que es **estacionaria**, por lo
que se adopta $d = 2$.
3. **Autocorrelación (Ítem 3):** la ACF de la serie original decae lentamente
(rezagos 1 a `r k_sig` significativos), lo que confirma la tendencia. Tras
una diferencia no queda ninguna autocorrelación significativa, y tras dos
solo permanece una autocorrelación negativa en el rezago 1
($r_1 = `r sprintf("%.2f", r_d2[1])`$), señal de que $d = 2$ podría ser algo
más de lo necesario.
4. **Implicación para el modelado:** la serie requiere diferenciación antes de
modelarse; $d = 2$ es la opción respaldada por las pruebas formales y
$d = 1$ queda como alternativa a comparar mediante criterios de información.
5. **Limitación:** con solo 18 observaciones, las pruebas de hipótesis y las
bandas de la ACF son aproximadas y de baja potencia; una serie más larga
permitiría conclusiones más sólidas.
# Referencias {.unnumbered}
- Hyndman, R. J., & Athanasopoulos, G. (2021). *Forecasting: Principles and
Practice* (3.ª ed.). OTexts.
- Dickey, D. A., & Fuller, W. A. (1979). Distribution of the estimators for
autoregressive time series with a unit root. *JASA*, 74(366), 427–431.
- Kwiatkowski, D., Phillips, P., Schmidt, P., & Shin, Y. (1992). Testing the
null hypothesis of stationarity against the alternative of a unit root.
*Journal of Econometrics*, 54, 159–178.
- Phillips, P. C. B., & Perron, P. (1988). Testing for a unit root in time
series regression. *Biometrika*, 75(2), 335–346.