<- "https://stats.oecd.org/sdmx-json/data/DP_LIVE/.CPI.../OECD?contentType=csv&detail=code&separator=comma&csv-lang=en"
url_inflation <- "./datos/ocde/DP_LIVE_22032023113248591.csv"
ruta_inflation <- here::here("datos", "ocde", "DP_LIVE_22032023113248591.csv")
ruta_inflation # curl::curl_download(url_inflation, ruta_inflation)
Curva de Phillips, ¿sigue siendo válida?
Intro
Estamos en el tercer día del curso de Introducción a Quarto y estamos practicando cómo hacer un tutorial. Como algunos de los asistentes al curso es posible que no sepan mucho R, vamos a replicar y ampliar este ejemplo.
Marco teórico
Nos da un poco igual pero el gráfico de @ThomIvar hace referencia a la curva de Phillips que según la Wikipedia es:
La curva de Phillips, en macroeconomía, representa una curva empírica de pendiente negativa que relaciona la tasa de inflación y la tasa de desempleo. – Articulo de la Wiki aquí
Abajo tienes el gráfico que ilustra la Curva de Phillips en la Wikipedia:
Por mucho que me empeñe yo, \(y_{t}=A_{1}y_{t-1}+A_{2}y_{t-2}+v_{t}\) no es la ecuación de la Curva de Phillips. Tampoco esta:
\[A(L)=(I_{K}-A_{1}L^{1}-A_{2}L^{2}-...-A_{p}L^{p})\]
Datos
Necesitamos datos de inflación y de tasa de desempleo. Vamos a usar los mimos datos que en el ejemplo original pero actualizados a 2023-06-21. Los datos provienen de la OCDE.
Antes de iniciar el análisis cargamos los paquetes de R que usaremos, solo que no vas a ver el chunk en el output final porque hemos puesto #| include: false
.
Inflación
Descargamos datos de inflación con este código:
Desempleo
Descargamos datos de desempleo con este código:
<- "https://stats.oecd.org/sdmx-json/data/DP_LIVE/.HUR.../OECD?contentType=csv&detail=code&separator=comma&csv-lang=en"
url_unemployment <- here::here("datos", "ocde", "DP_LIVE_22032023114049606.csv")
ruta_unemployment # curl::curl_download(url_unemployment, ruta_unemployment)
Resultados
Importamos los datos al Global env de R
:
<- readr::read_csv(ruta_inflation)
inflation_orig <- readr::read_csv(ruta_unemployment) unemployment_orig
Trabajamos los datos:
#- seleccionamos datos ---------------------------------------------------------
<- inflation_orig %>%
inflation ::filter(FREQUENCY == "M" & MEASURE == "AGRWTH", SUBJECT == "TOT") %>%
dplyrselect(place = LOCATION, date = TIME, cpi = Value)
<- unemployment_orig %>%
unemployment ::filter(FREQUENCY == 'M', SUBJECT == 'TOT') %>%
dplyrselect(place = LOCATION, date = TIME, rate = Value)
#- fusionamos los 2 df's -------------------------------------------------------
<- left_join(inflation, unemployment) %>%
df ::drop_na() %>%
tidyr::mutate(group = case_when(
dplyrstr_starts(date, "199") ~ "1991-1999",
str_starts(date, "200") ~ "2000-2009",
str_starts(date, "201") ~ "2010-2019",
str_starts(date, "202") ~ ">= 2020",
TRUE ~ "other" )) %>%
::filter(group != "other") dplyr
Hacemos el plot de @ThomIvar. Primero el plot básico:
<- c("G-7") #- seleccionamos "país"
my_country <- c("2000-2009", "2010-2019") #- seleccionamos periodos
my_periodos
<- df %>%
df_1p ::filter(place == my_country) %>%
dplyr::filter(group %in% my_periodos)
dplyr
# -- make plot for 1 country
<- ggplot(df_1p, aes(x = rate, y = cpi, group = group, color = group)) +
p0 geom_point(alpha = 0.5, size = 2.25)
p0
Y ahora el super-gráfico:
<- glue::glue("What happened to the <b>Phillips Curve</b> in ", my_country , "? (thanks to <b style='color:#fd5532'>@ThomIvar</b>)")
my_title
<- p0 + geom_smooth(method = 'lm', se = FALSE, linetype = 2) +
p1 scale_color_manual(values = c('#d1495b', '#00798c')) +
annotate('text', x = 5.5, y = 3.75, label = '2000-2009', color = '#d1495b',
family = 'American Typewriter', fontface = 'bold') +
annotate('text', x = 4.5, y = 0.75, label = '2010-2019', color = '#00798c',
family = 'American Typewriter', fontface = 'bold') +
labs(title = my_title,
subtitle = "The Phillips curve is an economic concept that states that inflation
and unemployment have an inverse relationship. However, in the <b style='color:#00798c'>
last decade</b> this relationship appears to have vanished.",
caption = '@ThomIvar • source: OECD (monthly, G7 countries)',
x = 'Unemployment rate, %',
y = 'Inflation rate, %') +
theme_void() +
theme(text = element_text('American Typewriter', color = 'grey30'),
legend.position = 'none',
plot.title = element_textbox_simple(size = 20, margin = margin(b = 0.15, unit = 'cm')),
plot.subtitle = element_textbox_simple(size = 11, color = 'grey60',
margin = margin(b = 0.25, unit = 'cm')),
plot.background = element_rect(fill = '#fffef7', color = '#fffef7'),
plot.caption = element_text(size = 10, color = 'grey80'),
plot.margin = margin(1, 1, 1, 1, 'cm'),
panel.grid = element_line(color = 'grey70', linetype = 'dotted'),
axis.title = element_text(margin = margin(t = 0.2, r = 0.2, unit = 'cm'), color = 'grey50'),
axis.title.y = element_text(angle = 90),
axis.text = element_text(color = 'grey70', size = 9,
margin = margin(t = 0.1, r = 0.1, unit = 'cm')),
axis.line = element_line(color = 'grey50'),
axis.ticks = element_line(color = 'grey50', size = 0.6),
axis.ticks.length = unit(0.10, 'cm'))
p1
Más resultados
Por hacer algo nuevo vamos a hacer un faceted-graph:
#- SEGUNDA parte (del script) --------------------------------------------------
#- hacemos el gráfico para varios países ---------------------------------------
<- c("ESP", "FRA", "GBR", "DEU", "USA", "JPN")
my_paises <- c("2000-2009", "2010-2019")
my_periodos
<- df %>%
df_paises ::filter(place %in% my_paises) %>%
dplyr::filter(group %in% my_periodos)
dplyr
#- plot feo para luego hacer un facetting
<- ggplot(df_paises, aes(x = rate, y = cpi, color = group)) +
p0 geom_point(alpha = 0.5, size = 0.75) +
geom_smooth(method = 'lm', se = FALSE, linetype = 1) +
scale_color_manual(values = c( '#d1495b', '#00798c', '#099205','#8e0592'))
#p0
#p0 + facet_wrap(vars(place))
<- p0 +
p1 facet_wrap(vars(place), scales = "free") +
labs(title = "What happened to the <b>Phillips Curve</b>? ",
subtitle = "The Phillips curve is an economic concept that states that inflation
and unemployment have a inverse relationship. However, we could find some exceptions for <b style='color:#d1495b'>
2000-2009</b> decade, and for the <b style='color:#00798c'>
last decade (2010-2019) </b>.",
caption = "@pjpv4444 (thanks to @ThomIvar) • source: OECD (monthly, G7 countries)",
x = 'Unemployment rate, %',
y = 'Inflation rate, %') +
theme_void() +
theme(text = element_text('American Typewriter', color = 'grey30'),
legend.position = 'none',
plot.title = element_textbox_simple(size = 20, margin = margin(b = 0.15, unit = 'cm')),
plot.subtitle = element_textbox_simple(size = 11, color = 'grey60',
margin = margin(b = 0.25, unit = 'cm')),
plot.background = element_rect(fill = '#fffef7', color = '#fffef7'),
plot.caption = element_text(size = 10, color = 'grey80'),
plot.margin = margin(1, 1, 1, 1, 'cm'),
panel.grid = element_line(color = 'grey70', linetype = 'dotted'),
axis.title = element_text(margin = margin(t = 0.2, r = 0.2, unit = 'cm'), color = 'grey50'),
axis.title.y = element_text(angle = 90),
axis.text = element_text(color = 'grey70', size = 9,
margin = margin(t = 0.1, r = 0.1, unit = 'cm')),
axis.line = element_line(color = 'grey50'),
axis.ticks = element_line(color = 'grey50', size = 0.6),
axis.ticks.length = unit(0.10, 'cm'))
p1
Tablas
Nos falta hacer una tabla, así que, por ejemplo, hacemos tabla de la inflación en el último mes que tengamos datos.
#- data munging
<- inflation_orig %>%
inflation ::filter(FREQUENCY == "M") %>%
dplyr::filter(MEASURE == "AGRWTH") %>%
dplyr::mutate(fecha = lubridate::ym(TIME)) %>%
dplyrselect(pais = LOCATION, fecha, inflacion = Value, tipo_inf = SUBJECT)
#- incorporar region para filtrar grupos de países
<- countrycode::codelist %>%
zz select(iso.name.en, region, region23, wb, fips, ioc, imf, iso2c, iso3c, ecb, eurostat, continent, eu28, un, un.region.name)
<- left_join(inflation, zz, by = join_by(pais == iso3c) ) # %>% distinct(pais, .keep_all = TRUE)
inflation
#- solo Europa (q no sea Europa del Este) --------------------------------------
<- inflation %>%
df ::filter(un.region.name %in% c("Europe")) %>%
dplyr::filter(!(region23 %in% c("Eastern Europe")))
dplyr
<- "Tasas de inflación interanual en Europa (febrero 2023)"
my_title <- "Países europeos y <span style='color:#3569a4'> España </span> "
my_subtitle
#- paso a ancho ----------------------------------------------------------------
<- df %>%
df select(pais, iso.name.en, fecha, inflacion, tipo_inf) %>%
pivot_wider(names_from = tipo_inf, values_from = inflacion)
#- banderas --------------------------------------------------------------------
<- df %>% #- fips
df mutate(iso2 = countrycode::countrycode(sourcevar = pais, origin = "iso3c", destination = "iso2c", warn = FALSE)) %>%
mutate(iso2 = tolower(iso2)) %>%
mutate(flag_URL = glue::glue('https://hatscripts.github.io/circle-flags/flags/{iso2}.svg'))
#- selecciono fecha ------------------------------------------------------------
<- max(inflation$fecha)
my_fecha <- "2023-02-01"
my_fecha
<- df %>% dplyr::filter(fecha == my_fecha)
df
#- ordeno de + a - la inf. total -----------------------------------------------
<- df %>% select(1,2, flag_URL, 3, 6, everything()) %>% arrange(desc(TOT), ENRG) %>% select(-iso2)
df
<- df %>% mutate(FOOD = FOOD/max(FOOD)) df
- Tabla con el paquete
DT
<- df %>% select(-flag_URL)
df_DT ::datatable(df_DT)
DT::datatable(df_DT, filter = 'top', extensions = "Scroller") DT
- Ahora tabla chula
#- con gt: https://gt.rstudio.com/
#df <- df %>% mutate(across(where(is.numeric), \(x) round(x, digits = 2)))
<- df %>%
tt_6 gt(rowname_col = "pais") %>%
tab_header(title = my_title, subtitle = md(my_subtitle)) %>%
tab_source_note(md("Fuente: datos proveniente de la [OCDE](http://www.oecd.org/)")) %>%
::gt_theme_nytimes() %>%
gtExtras::gt_img_rows(flag_URL, height = 25) %>%
gtExtras::gt_merge_stack(col2 = iso.name.en, col1 = pais) %>%
gtExtrastab_footnote(footnote = "Tasa de inflación eliminando el efecto de la energía y los alimentos",
location = cells_column_labels(columns = TOT_FOODENRG)) %>%
cols_label(TOT = md("**Total**"), ENRG = "Energética", FOOD = "Alimentos", TOT_FOODENRG = "Total sin ..." ) %>%
cols_align(align = "center") %>%
cols_align(align = "left", columns = fecha) %>%
cols_width(columns = TOT ~ px(120)) %>%
fmt_percent(columns = c(TOT, ENRG, FOOD, TOT_FOODENRG), scale_values = FALSE) %>%
tab_style(style = cell_text(color = "#f97d64"),
locations = cells_body(columns = TOT,
rows = TOT >= mean(TOT))) %>%
tab_style(style = cell_text(color = "#f97d64"),
locations = cells_body(columns = FOOD,
rows = FOOD >= mean(FOOD))) %>%
tab_style(style = cell_text(color = "#f97d64"),
locations = cells_body(columns = ENRG,
rows = ENRG >= mean(ENRG))) %>%
tab_style(style = cell_text(color = "#3569a4"),
locations = cells_body(rows = pais == "ESP")) %>%
data_color(columns = c(TOT_FOODENRG),
colors = scales::col_numeric(palette = "Reds", domain = NULL))
#gtExtras::gt_plt_bar_pct(column = FOOD, scaled = TRUE, fill = "blue", background = "lightblue")
tt_6
Tasas de inflación interanual en Europa (febrero 2023) | ||||||
Países europeos y España | ||||||
flag_URL | fecha | Total | Energética | Alimentos | Total sin ...1 | |
---|---|---|---|---|---|---|
LVA
Latvia |
2023-02-01 | 20.26% | 46.43% | 0.84% | 10.51% | |
LTU
Lithuania |
2023-02-01 | 18.74% | 29.21% | 1.00% | 12.17% | |
EST
Estonia |
2023-02-01 | 17.55% | 30.28% | 0.84% | 12.13% | |
AUT
Austria |
2023-02-01 | 10.88% | 26.52% | 0.54% | 8.61% | |
ISL
Iceland |
2023-02-01 | 10.20% | 14.58% | 0.40% | 9.47% | |
SVN
Slovenia |
2023-02-01 | 9.28% | 6.14% | 0.61% | 7.67% | |
ITA
Italy |
2023-02-01 | 9.15% | 28.20% | 0.44% | 4.79% | |
FIN
Finland |
2023-02-01 | 8.80% | 16.83% | 0.54% | 6.60% | |
DEU
Germany |
2023-02-01 | 8.68% | 19.98% | 0.69% | 5.86% | |
IRL
Ireland |
2023-02-01 | 8.46% | 29.30% | 0.43% | 5.56% | |
PRT
Portugal |
2023-02-01 | 8.25% | 1.94% | 0.71% | 7.21% | |
NLD
Netherlands (the) |
2023-02-01 | 7.96% | −1.07% | 0.59% | NA | |
DNK
Denmark |
2023-02-01 | 7.60% | 13.97% | 0.49% | 5.80% | |
BEL
Belgium |
2023-02-01 | 6.62% | −7.93% | 0.56% | 6.90% | |
NOR
Norway |
2023-02-01 | 6.30% | 12.44% | 0.29% | 5.60% | |
FRA
France |
2023-02-01 | 6.28% | 13.95% | 0.52% | 3.57% | |
GRC
Greece |
2023-02-01 | 6.13% | −5.22% | 0.49% | 6.34% | |
ESP
Spain |
2023-02-01 | 6.03% | −8.87% | 0.55% | 5.19% | |
LUX
Luxembourg |
2023-02-01 | 4.31% | −1.98% | 0.43% | 3.63% | |
CHE
Switzerland |
2023-02-01 | 3.37% | 16.65% | 0.21% | 2.03% | |
SWE
Sweden |
2023-02-01 | NA | 11.97% | 0.69% | 10.50% | |
Fuente: datos proveniente de la OCDE | ||||||
1 Tasa de inflación eliminando el efecto de la energía y los alimentos |
Mapas
Volvemos a seleccionar datos
<- inflation_orig %>%
inflation ::filter(FREQUENCY == "M" & MEASURE == "AGRWTH", SUBJECT == "TOT") %>%
dplyrselect(place = LOCATION, date = TIME, cpi = Value)