18 mar 2024

Recesión plot en R usando ggplot (recession plot in r)

En el siguiente ejemplo se simular y replica -parcialmente- un ejemplo usado por el FMI para ilustrar la importancia del uso de series de tiempo de alta frecuencia para el análisis de la coyuntura económica. Puntualmente, plantean que las series anuales pueden ocultar dinámicas relevantes para la elaboración de análisis. Resaltar que el código fue creado a partir de preguntas a chatgpt https://chat.openai.com/. 

En este ejemplo simulamos una caminata aleatoria y luego la graficamos en ggplot2.

 1.       Simular la data

 # Definir la función para simular una caminata aleatoria
simular_caminata_aleatoria <- function(n, start, sigma){
  eps <- rnorm(n, mean = 0, sd = sigma)
  camino <- numeric(n)
  camino[1] <- start + eps[1]
  for(i in 2:n){
    camino[i] <- camino[i-1] + eps[i]
  }
  return(camino)
}
 
# Definir los parámetros
set.seed(123)  # Fijar semilla para reproducibilidad
trimestres <- seq(as.Date("2015-01-01"), as.Date("2020-12-31"), by = "3 months")
n_trimestres <- length(trimestres)
sigma <- 1  # Desviación estándar para la caminata aleatoria
 
# Simular datos trimestrales
datos_trimestrales <- simular_caminata_aleatoria(n_trimestres, 100, sigma)
 
# Calcular promedio anual
promedio_anual <- tapply(datos_trimestrales, as.integer(format(trimestres, "%Y")), mean)
 
# Crear dataframe
data <- data.frame(trimestre = trimestres,
                   dato_trimestral = datos_trimestrales,
                   promedio_anual = rep(promedio_anual, each = 4))
 
> data
    trimestre dato_trimestral promedio_anual
1  2015-01-01        99.43952       100.0639
2  2015-04-01        99.20935       100.0639
3  2015-07-01       100.76806       100.0639
4  2015-10-01       100.83856       100.0639
5  2016-01-01       100.96785       102.1683
6  2016-04-01       102.68292       102.1683

 2.       Graficar en ggplot

Posteriormente, se indican las fechas de inicio y fin para los periodos que deseamos resaltar, en el eje x se colocan las fechas (aes(x = trimestre)), mientras que se usa la función geom_rect para resaltar el periodo comprendido al año 2017. Posteriormente se agregan los gráficos de línea correspondiente a la serie anual y trimestral. La idea del FMI (https://www.cepal.org/sites/default/files/document/files/sna2008_web.pdf) es que la serie puede empezar a crecer, cuando en realidad determino

 # Definir límites para el área sombreada (2012)
inicio_recesion <- as.Date("2017-01-01")
fin_recesion <- as.Date("2017-12-31")
 
# Graficar series de tiempo
ggplot(data, aes(x = trimestre)) +
  geom_rect(xmin = inicio_recesion,
            xmax = fin_recesion,
            ymin = -Inf,
            ymax = Inf,
            fill = gray(0.9), alpha = 0.7) +
  annotate("text",
             x = as.Date("2017-07-01"),
             y = max(data$dato_trimestral),
         label = "2017",
         color = "black", size = 3) +
   geom_line(aes(y = dato_trimestral, color = "Trimestral")) +
  geom_point(aes(y = dato_trimestral)) +
   geom_line(aes(y = promedio_anual, color = "Promedio anual"), linetype = "dashed") +
  labs(title = element_blank(),
           x =  element_blank(),
           y =  element_blank(),
       color =  element_blank()) +
  theme_classic() +
  theme(legend.position = c(0.8,0.1))

7 mar 2024

Filtro Hodrick Prescott informado en Matlab e Iris

El siguiente ejemplo muestra cómo obtener estimaciones de la brecha de producción usando el filtro hp para distintos periodos. En primer lugar, cargamos los datos del gdp real, disponible en el Banco Central en frecuencia trimestral.

Tomamos el logaritmo del PIB y realizamos el ajuste estacional usando el procedimiento x12.

%Do housekeeping   
close all; clear; clc;
 
load('data_for_model_dom.mat');
 
dq.l_gdp = 100*log(dq.GDP_U);
dq.l_gdp_adj = x12(dq.l_gdp);
 
dbplot(dq,sdate:ehist,{'"GDP and potential GDP" [l_gdp,l_gdp_adj]'},'Linewidth',2);


Posteriormente, estimamos el PIB potencial usando el filtro hp de IRIS (versión [IrisToolbox] for Macroeconomic Modeling Release 20211222).

[dq.l_gdp_bar,dq.l_gdp_gap] = hpf(dq.l_gdp);
[dq.l_gdp_bara,dq.l_gdp_gapa] = hpf(dq.l_gdp_adj);
 
% set important dates
sdate = qq(2012,1);
ehist = qq(2023,4);
 
dbplot(dq,sdate:ehist,{'"GDP and potential GDP" [l_gdp_adj, l_gdp_bara]'},'Linewidth',2);


Finalmente, usamos el objeto lbar_tnd para informarle que valores queremos tenga el PIB potencial en determinados periodos. Note por ejemplo que sin informar el efecto COVID tienen un efecto sobre el PIB potencial que inicia antes de 2020.

lbar_tnd = Series([sdate,qq(2012,2)    ,qq(2019,4)],...
                 [dq.l_gdp(qq(2012,2)),dq.l_gdp(qq(2012,2)),520]);
[dq.l_gdp_bara1,dq.l_gdp_gapa1] = hpf(dq.l_gdp_adj,'level',lbar_tnd);
 
dbplot(dq,sdate:ehist,...
    {'"GDP and potential GDP" [l_gdp_adj, l_gdp_bara, l_gdp_bara1]', ...
    '"Cycle GDP" [l_gdp_gapa1]'},...
    'Linewidth',2, ...
    'zeroline',true, ...
    'highlight',qq(2020,1):qq(2020,4));
legend('Obs','hp','Location','best');




27 dic 2023

Exportar a Excel múltiples data frame de manera simultanea en R

En el siguiente ejemplo mostramos como exportar multiples data frame a Excel de forma simultanea en R. Primero segmentamos la base de datos en varios datos.

iris_setosa <- iris[iris$Species == "setosa",]
iris_setosa <- iris[iris$Species == "versicolor",]
iris_setosa <- iris[iris$Species == "virginica",]

Primero creamos una función que exporta un data frame a R. Teniendo el nombre de la base de datos en formato texto, creamos el nombre con el que vamos a exportar el archivo (que es el mismo nombre del objeto que vamos a exportar: paste0(objeto, ".xlsx")). Posteriormente, exportamos este archico a Excel usando la función write_xlsx del paquete writexl.

exportar_a_excel <- function(objeto) {
  nombre_archivo <- paste0(objeto, ".xlsx")
  writexl::write_xlsx(get(objeto), nombre_archivo)
}

Finalmente, usamos el paquete purr y su función map para aplicar la función que acabamos de crear para múltiples objetos. Primero creamos un vector de caracteres con todos los objetos cuyo nombre inicien con “iris_”, y posteriormente aplicamos la función exportar_a_excel, usando la función map.

library(purrr)
library(writexl)
 
objetos_result <- ls(pattern = "^iris_")
map(objetos_result, exportar_a_excel)

25 oct 2023

Una rápida introducción a la gestión de base de datos con dplyr en 10 minutos

Aquí proponemos una pequeña base de datos, para introducir el uso de dplyr como herramienta de gestión de base de datos en R.

data1 <- data.frame(
  id = 1:8,
  edad = c(8,9,12,22,14,17,22,16),
  mujer = c(T,T,F,F,F,T,T,F),
  prov = c("azua","azua","azua","Bani","Bani","Ocoa","Bani","Ocoa"),
  nota = c(60,70,71,82,92,80,95,72),
  nota2 = c(60,70,71,82,92,80,95,72),
  carrera = c("Ecn","Ing","Ecn","Ing","Ecn","Ing","Ecn","Ing")
)
 
data1
  id edad mujer prov nota nota2 carrera
1  1    8  TRUE azua   60    60     Ecn
2  2    9  TRUE azua   70    70     Ing
3  3   12 FALSE azua   71    71     Ecn
4  4   22 FALSE Bani   82    82     Ing
5  5   14 FALSE Bani   92    92     Ecn
6  6   17  TRUE Ocoa   80    80     Ing
7  7   22  TRUE Bani   95    95     Ecn
8  8   16 FALSE Ocoa   72    72     Ing

Con el siguiente ejemplo solo queremos ilustrar que dplyr es una alternativa a las operaciones tradicionales con R:

Nota promedio

Base de R

mean(nota[prov %in% c("Bani","Ocoa")])

[1] 84.2

Paquete dplyr

 Library(tidyverse)
 
data1 |>
  dplyr::filter(prov %in% c("Bani","Ocoa")) |>
  summarise(mean(nota))
   mean(nota)
1       84.2

1. Select. Permite seleccionar columnas o variables de una base de datos. De la base anterior, usamos select para seleccionar las columnas id y edad. Note que se usa dplyr::select, para especificar de que paquete deseamos usar la función select, dado que existen varios paquetes con funciones de este nombre.

data1 |>
  dplyr::select(id,edad)
  id edad
1  1    8
2  2    9
3  3   12
4  4   22
5  5   14
6  6   17
7  7   22
8  8   16

2. filter. Condicionar las observaciones deseadas. Es un filtro al permitir discriminar entre observaciones en función del cumplimiento de alguna condición de las mismas. En el ejemplo siguiente usamos select para elegir todas las variables (everything), y posteriormente filtramos para solo acceder a las personas con calificación mayor a 69.

 data1 |>
  dplyr::select(everything()) |>
  dplyr::filter(nota > 69)
  id edad mujer prov nota nota2 carrera
1  2    9  TRUE azua   70    70     Ing
2  3   12 FALSE azua   71    71     Ecn
3  4   22 FALSE Bani   82    82     Ing
4  5   14 FALSE Bani   92    92     Ecn
5  6   17  TRUE Ocoa   80    80     Ing
6  7   22  TRUE Bani   95    95     Ecn
7  8   16 FALSE Ocoa   72    72     Ing

3. mutate. Se crea para crear una variable o crear una variable nueva. En este sentido podemos usar los operadores de R para crear las variables que entendamos. Por ejemplo, ahora creamos la variable edad al 2.

 data1 |>
  dplyr::select(everything()) |>
  dplyr::filter(nota > 69) |>
  mutate(Edad2 = edad^2)
  id edad mujer prov nota nota2 carrera Edad2
1  2    9  TRUE azua   70    70     Ing    81
2  3   12 FALSE azua   71    71     Ecn   144
3  4   22 FALSE Bani   82    82     Ing   484
4  5   14 FALSE Bani   92    92     Ecn   196
5  6   17  TRUE Ocoa   80    80     Ing   289
6  7   22  TRUE Bani   95    95     Ecn   484
7  8   16 FALSE Ocoa   72    72     Ing   256

4. summarise. Permite crear un resumen de la base de datos, análisis condicional. Por ejemplo, sacamos las notas promedio por carrera. Note que ahora debemos indicar cual es la función de agregación de las variables.

data1 |>
  dplyr::select(everything()) |>
  dplyr::filter(nota > 69) |>
  group_by(carrera) |>
  summarise(mean(nota))
 
# A tibble: 2 x 2
  carrera `mean(nota)`
  <chr>          <dbl>
1 Ecn               86
2 Ing               76

Podemos agregar múltiples capas en group_by:

data1 |>
  dplyr::select(everything()) |>
  dplyr::filter(nota > 69) |>
  group_by(carrera, prov) |>
  summarise(promedio = mean(nota))
 
`summarise()` has grouped output by 'carrera'. You can override using the `.groups` argument.
# A tibble: 5 x 3
# Groups:   carrera [2]
  carrera prov  promedio
  <chr>   <chr>    <dbl>
1 Ecn     azua      71 
2 Ecn     Bani      93.5
3 Ing     azua      70 
4 Ing     Bani      82 
5 Ing     Ocoa      76

5. Cambiar la estructura de una base de datos. Por el formato wide:

data1 |>
  dplyr::select(id,prov,starts_with("nota"))
 
  id prov nota nota2
1  1 azua   60    60
2  2 azua   70    70
3  3 azua   71    71
4  4 Bani   82    82
5  5 Bani   92    92
6  6 Ocoa   80    80
7  7 Bani   95    95
8  8 Ocoa   72    72

Ahora, la base anterior la transformamos en formato long.

data1 |>
  dplyr::select(id,starts_with("nota")) |>
  pivot_longer(cols = !id, names_to='asigna', values_to='valor')
 
# A tibble: 16 x 3
      id asigna valor
   <int> <chr>  <dbl>
 1     1 nota      60
 2     1 nota2     60
 3     2 nota      70
 4     2 nota2     70
 5     3 nota      71
 6     3 nota2     71
 7     4 nota      82
 8     4 nota2     82
 9     5 nota      92
10     5 nota2     92
11     6 nota      80
12     6 nota2     80
13     7 nota      95
14     7 nota2     95
15     8 nota      72
16     8 nota2     72

6. Arrange. Organizar la base de datos. En este caso, organizamos la base de datos en función del valor de una o múltiples variable.

 data_long <- data1 |>
  dplyr::select(id,starts_with("nota")) |>
  pivot_longer(cols = !id, names_to='asigna', values_to='valor') |>
  arrange(desc(asigna))
 
data_long
 
# A tibble: 16 x 3
      id asigna valor
   <int> <chr>  <dbl>
 1     1 nota2     60
 2     2 nota2     70
 3     3 nota2     71
 4     4 nota2     82
 5     5 nota2     92
 6     6 nota2     80
 7     7 nota2     95
 8     8 nota2     72
 9     1 nota      60
10     2 nota      70
11     3 nota      71
12     4 nota      82
13     5 nota      92
14     6 nota      80
15     7 nota      95
16     8 nota      72

 7. inner. Permite combinar información de distintas bases relacionadas.

 inner_join(data_long, data1, by = "id")  |>
  dplyr::select(-starts_with("nota"))
 
# A tibble: 16 x 7
      id asigna valor  edad mujer prov  carrera
   <int> <chr>  <dbl> <dbl> <lgl> <chr> <chr> 
 1     1 nota2     60     8 TRUE  azua  Ecn   
 2     2 nota2     70     9 TRUE  azua  Ing   
 3     3 nota2     71    12 FALSE azua  Ecn   
 4     4 nota2     82    22 FALSE Bani  Ing   
 5     5 nota2     92    14 FALSE Bani  Ecn   
 6     6 nota2     80    17 TRUE  Ocoa  Ing   
 7     7 nota2     95    22 TRUE  Bani  Ecn   
 8     8 nota2     72    16 FALSE Ocoa  Ing   
 9     1 nota      60     8 TRUE  azua  Ecn   
10     2 nota      70     9 TRUE  azua  Ing   
11     3 nota      71    12 FALSE azua  Ecn   
12     4 nota      82    22 FALSE Bani  Ing   
13     5 nota      92    14 FALSE Bani  Ecn   
14     6 nota      80    17 TRUE  Ocoa  Ing   
15     7 nota      95    22 TRUE  Bani  Ecn   
16     8 nota      72    16 FALSE Ocoa  Ing

26 sept 2023

Modelo de Oferta y Demanda en Matlab

Syms es una función que se utiliza para declarar símbolos o variables simbólicas. Estos símbolos no tienen un valor numérico asignado de forma predeterminada, en contraste con las variables normales en MATLAB que almacenan valores numéricos. En su lugar, los símbolos se utilizan para realizar cálculos simbólicos, como álgebra simbólica, cálculo, manipulación de expresiones matemáticas y resolución de ecuaciones simbólicas.

syms x
ezplot(x^2 - x*1.5, [-2 2])

Puedes utilizar syms en MATLAB para simular las curvas de oferta y demanda mediante ecuaciones simbólicas y luego graficar los resultados. Definiendo con syms las variables del modelo, posteriormente necesitamos definir las expresiones que definen las curvas de oferta y demanda y resolver el sistema de ecuaciones (solve). Posteriormente se utiliza la función subs, que permite remplazar valores dentro de una expresión simbólica. Es decir, dentro de la función demanda, podemos recuperar los valores para el precio de demanda que corresponden a cada una de las cantidades demandadas[1].

 syms P Q
 
oferta = 1.2*Q + 5;
demanda = 10 - 0.45*Q;
 
equilibrio = solve(oferta == demanda, [P, Q]);
 
Q_values = linspace(0, 10, 100); % Valores de Q para el gráfico
 
oferta_values = subs(oferta, Q, Q_values);
demanda_values = subs(demanda, Q, Q_values);

Finalmente, se grafican los resultados. Teniendo en cuenta que, en MATLAB, se utiliza el comando figure antes de crear un gráfico para crear una nueva ventana de figura o lienzo de dibujo en la que se mostrará el gráfico. Esto es útil cuando deseas tener múltiples gráficos en ventanas separadas o cuando deseas personalizar aspectos específicos de la figura, como su tamaño o propiedades. Hold on permite anexar series a un mismo gráfico, como múltiples layers en el caso de ggplot2 para los usuarios de R. Finalmente, se agregan las etiquetas y las opciones sobre formato del gráfico.

figure;
plot(Q_values, oferta_values, 'b', 'LineWidth', 2);
hold on;
plot(Q_values, demanda_values, 'r', 'LineWidth', 2);
scatter(equilibrio.Q, equilibrio.P, 100, 'k', 'filled'); % Punto de equilibrio
xlabel('Cantidad (Q)');
ylabel('Precio (P)');
title('Curvas de Oferta y Demanda');
legend('Oferta', 'Demanda', 'Equilibrio', 'Location','best');
grid on;


[1] syms x y
 
expr = x^2 + y;
valor_x = 3;
valor_y = 4;
 
resultado = subs(expr, [x, y], [valor_x, valor_y]);

Recesión plot en R usando ggplot (recession plot in r)

En el siguiente ejemplo se simular y replica -parcialmente- un ejemplo usado por el FMI para ilustrar la importancia del uso de series de ti...