The R software can be downloaded for free from the internet r-project. One of the most convenient and efficient interfaces for using R can also be downloaded for free from the internet: RStudio. There is also the possibility of working on RStudio via the cloud at the following address: posit.cloud. In this latter way, you can work online even if R is not installed on the computer you are working on. R is available for different operating systems: Linux, Apple and Microsoft.
The website to refer to for IMF data is https://www.imf.org/external/datamapper/datasets.
In the “World Economic Outlook” (WEO) section there are the main economic indicators (GDP, inflation, population, trade balance and public finances).
To access these data it is necessary to install the
imfapi package.
The command to install a package is
install.packages('NAME'). However, in the RStudio interface there is a section (bottom right)Packageswhere you can search for a package and install it
Once the imfapi package has been loaded into memory, you
can download the data related to the chosen countries.
Countries are represented by the three-letter code that can be found at this address.
In the case we are interested in we have: Germany DEU, France FRA, Italy ITA and Spain ESP.
library(imfapi)
dati=imf_get(
dataflow_id = "WEO",
dimensions = list(FREQUENCY = c("A"),
COUNTRY = c('DEU','FRA','ITA','ESP'))
)
To inspect the variable dati you can use the command View(dati).
The downloaded data contain all the historical series available on the IMF website. For us, in particular, the one related to GDP at current prices in (billions of) US dollars is of interest, whose code is NGDPD (the code can be found within the URL address related to this variable).
With the command View(dati) we observe which columns are inside the variable dati. The “series_id” column reports the codes of the historical series (we are interested in NGDPD), while the “entity_id” column reports the country codes (we are interested in the three codes seen previously).
Within the variable dati we can select some values using square brackets, inside which we indicate the desired codes.
DEU=dati[dati$INDICATOR=='NGDPD' & dati$COUNTRY=='DEU',]$OBS_VALUE
FRA=dati[dati$INDICATOR=='NGDPD' & dati$COUNTRY=='FRA',]$OBS_VALUE
ITA=dati[dati$INDICATOR=='NGDPD' & dati$COUNTRY=='ITA',]$OBS_VALUE
ESP=dati[dati$INDICATOR=='NGDPD' & dati$COUNTRY=='ESP',]$OBS_VALUE
In the previous code, the symbol “&” indicates that both conditions must be satisfied: that is, we will take only the data that contain, at the same time, the code NGDPD and the code of the country of interest.
The dollar symbol “$” indicates, within a variable made up of multiple columns, which columns we want to extract.
The comma at the end of the square brackets indicates that all other data (i.e., those not identified by the previous conditions) must be taken in their entirety.
Among everything that has been selected, only the content of the “value” column is taken.
To transform data and dates into a time series we use the zoo package (which must be installed beforehand).
Within the package, the zoo command allows you to associate numeric values (as first input) with dates (second input).
library(zoo)
##
## Caricamento pacchetto: 'zoo'
## I seguenti oggetti sono mascherati da 'package:base':
##
## as.Date, as.Date.numeric
PIL=zoo(cbind(DEU,FRA,ITA,ESP),seq(1980,2025))
The cbind command creates a matrix by binding, side by
side, each variable indicated in the arguments of the command.
At this point we can graphically represent the time series. The simple plot command returns the following.
plot(PIL)
We thus see that the time series are represented “stacked” separately.
To represent them all on the same graph you must specify that all the
traces must be shown on the same panel with the option
screens=1.
plot(PIL,screens=1)
At this point, however, the traces must be differentiated using
different colors. The option is col inside which you can
indicate colors by their names in English.
plot(PIL,screens=1,col=c('black','red','blue','orange'))
To make the traces more visible you can specify a particular line
thickness using the option lwd: line width.
plot(PIL,screens=1,col=c('black','red','blue','orange'),lwd=2)
We can also add a grid in the background of the Cartesian plane and insert a legend in the most appropriate position.
plot(PIL,screens=1,col=c('black','red','blue','orange'),lwd=2)
grid()
legend('topleft',legend=c('Germany','France','Italy','Spain'),
col=c('black','red','blue','orange'),lwd=2,bty='n')
The command bty within the legend indicates the box
type. The legend, without any specification of this option, appears
inside a rectangle. If we want the legend not to be framed, the value n
indicates that we do not want to add a border.
To make GDP values comparable with each other, we can make them all start from the same value (by convention equal to 1) and on the same date.
The command we need, in this case, is sweep which allows
applying a transformation to the data of a table. We can, for example,
define the following command.
PIL1=sweep(PIL,2,PIL[1],'/')
The syntax means: we take the variable PIL and, for each column (dimension 2 of the matrix), we take the first value of the column PIL[1] and divide ‘/’ the entire column by this value.
We can thus represent the new variable on a graph.
plot(PIL1,screens=1,col=c('black','red','blue','orange'),lwd=2)
grid()
legend('topleft',legend=c('Germany','France','Italy','Spain'),
col=c('black','red','blue','orange'),lwd=2,bty='n')
To appreciate how the relative position of the countries changes by changing the start date of the analysis, we can represent the same type of graph, but starting from 2008.
The window command allows us to select a time window
within a time series (indicating a start date and an end date).
PIL2=window(PIL,start=2008)
PIL2=sweep(PIL2,2,PIL2[1],'/')
plot(PIL2,screens=1,col=c('black','red','blue','orange'),lwd=2)
grid()
legend('topleft',legend=c('Germany','France','Italy','Spain'),
col=c('black','red','blue','orange'),lwd=2,bty='n')
Finally, we observe how the ranking changes starting from 2020.
PIL3=window(PIL,start=2020)
PIL3=sweep(PIL3,2,PIL3[1],'/')
plot(PIL3,screens=1,col=c('black','red','blue','orange'),lwd=2)
grid()
legend('topleft',legend=c('Germany','France','Italy','Spain'),
col=c('black','red','blue','orange'),lwd=2,bty='n')
The Yahoo website contains numerous historical series of financial data. For us, in particular, the two indices are of interest:
^GSPC^NDXTo download data from Yahoo you need to install the
quantmod package. The getSymbols command is
then used to connect R with Yahoo’s database and download the data.
library(quantmod)
## Caricamento del pacchetto richiesto: xts
## Caricamento del pacchetto richiesto: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
getSymbols(c('^GSPC','^NDX'),
src='yahoo',return.class='zoo',
from='1985-01-01')
## [1] "GSPC" "NDX"
The option src indicates the data source; this option is
necessary because quantmod also allows downloading data
from other online databases.
The option return.class allows choosing what type of
output we want from the getSymbols command: we want a
zoo time series, as already seen in the previous
paragraph.
To check what the downloaded variables contain, we use the command
View(GSPC), thus observing that we downloaded the opening
prices, the highs, the lows, the closing prices, the volumes and the
adjusted closes. We are interested only in the adjusted closes, which we
select with the following command.
S=merge(GSPC$GSPC.Adjusted,NDX$NDX.Adjusted,
all=FALSE)
The merge command merges the two variables based on
dates. The all option specifies whether we want, as output,
all observations, or not. If the option is indicated as
FALSE, only the dates for which values are available for
all variables will be returned.
Once the time series S has been created we can plot it
as already seen previously. In this case we also specify the label to
give to the x-axis (with the option xlab – which we keep
empty in the example) and the label for the y-axis (with the option
ylab).
plot(S,screens=1,col=c('blue','red'),lwd=2,
xlab='',ylab='Stock market indices')
grid()
legend('topleft',legend=c('S&P 500','NASDAQ 100'),
col=c('blue','red'),lwd=2,bty='n')
To highlight important dates within the graph, we define the relevant dates using the following command.
date=as.Date(c('2000-03-10',
'2008-09-15',
'2020-03-20'))
The as.Date command transforms a string (or a series of
strings) into a date: the string must be defined in the form
year-month-day where the year must have 4 digits, while
month and day must have 2 digits.
We can also define texts to add to the graph.
eventi=c('Dot-com\nbubble',
'Lehman\nBrothers',
'Pandemic')
The strings contain the command \n which separates one
line from the next with a line break.
To add vertical lines to the previous graph, the abline
command allows defining straight lines to overlay on the graph. The
text command, instead, allows adding text to a graph.
plot(S,screens=1,col=c('blue','red'),lwd=2,
xlab='',ylab='Stock market indices')
grid()
legend('topleft',legend=c('S&P 500','NASDAQ 100'),
col=c('blue','red'),lwd=2,bty='n')
abline(v=date,lty=2)
text(date,max(S),labels=eventi,pos=1)
The option v in the abline command
indicates “vertical”: therefore, vertical lines are created at the
x-values in the variable date and all the lines are dashed
(option lty=2).
The text command inserts text at the coordinates given
by the first two arguments. We take the x-values from the variable
date and as y-value we take the maximum of the prices. The
labels are inserted in the variable eventi. Finally, the
position pos indicates where the text must appear relative
to the point indicated by the coordinates: 1 indicates the position
below the point, 2 indicates to the left, 3 indicates above and 4
indicates to the right.
The quantmod package also allows downloading data from
the FRED database managed by the US Federal Reserve. The website is https://fred.stlouisfed.org/.
By searching for the 10-year interest rate for Italy, for example,
you obtain the time series with label: IRLTLT01ITM156N. The code
IT within the label indicates Italy. We can therefore
download different countries by changing only the two central
letters.
library(quantmod)
getSymbols(c('IRLTLT01DEM156N',
'IRLTLT01FRM156N',
'IRLTLT01ITM156N',
'IRLTLT01ESM156N',
'IRLTLT01GRM156N'),
src='FRED',
return.class='zoo')
## [1] "IRLTLT01DEM156N" "IRLTLT01FRM156N" "IRLTLT01ITM156N" "IRLTLT01ESM156N"
## [5] "IRLTLT01GRM156N"
This time we downloaded the data from “FRED”, indicating it as the
source (src) of the data.
Now we merge all interest rates into a single matrix.
tassi=merge(IRLTLT01DEM156N,
IRLTLT01FRM156N,
IRLTLT01ITM156N,
IRLTLT01ESM156N,
IRLTLT01GRM156N)
By plotting the data, we obtain the following result.
plot(tassi,screens=1,
col=c('black','red','blue','orange','darkgreen'),
lwd=2,xlab='')
grid()
legend('topleft',legend=c('DE','FR','IT','ES','GR'),
col=c('black','red','blue','orange','darkgreen'),
lwd=2,bty='n')
This graph shows the time series even for dates corresponding to
which not all interest rates are available (in fact we did not specify
the option all=FALSE).
To omit missing data (not available na) you need to use
the na.omit command.
plot(na.omit(tassi),screens=1,
col=c('black','red','blue','orange','darkgreen'),
lwd=2,xlab='')
grid()
legend('topleft',legend=c('DE','FR','IT','ES','GR'),
col=c('black','red','blue','orange','darkgreen'),
lwd=2,bty='n')
To calculate the spread between two rates (Italian and German) it is
sufficient to extract, from the variable tassi, the columns
related to the two interest rates and compute their difference.
spread=tassi$IRLTLT01ITM156N-tassi$IRLTLT01DEM156N
spread=na.omit(spread)
plot(spread,col='blue',lwd=2,
xlab='',ylab='IT DE spread')
grid()
On the graph you can overlay colored rectangles with the
rect command, which takes as input the coordinates of the
lower-left corner and the upper-right corner of the rectangle. The value
of the dates (x-axis) is extracted from the time series with the
time command.
To make colors transparent it is necessary to use colors defined as a
combination of red, green and blue with the command
rgb(x,y,z,a) where x is the percentage of red,
y the percentage of green and z the percentage
of blue; finally a is the degree of transparency (between
0, color absent, and 1, fully opaque color, not transparent).
Recalling that yellow is a combination of green and red, we can give the following commands.
plot(spread,col='blue',lwd=2,
xlab='',ylab='IT DE spread')
grid()
#green rectangle
rect(min(time(spread)),0,
max(time(spread)),1,
col=rgb(0,1,0,0.2),
border='NA')
#yellow rectangle
rect(min(time(spread)),1,
max(time(spread)),3,
col=rgb(1,1,0,0.2),
border='NA')
#red rectangle
rect(min(time(spread)),3,
max(time(spread)),max(spread),
col=rgb(1,0,0,0.2),
border='NA')
On the FRED website we can transform the data through the interface
of the website itself; for example, we can calculate the percentage
changes of each variable compared to its value in the previous period or
compared to its value in the previous year. These transformations can
also be carried out in R, but using a specific package:
fredr.
To use this package you need to register on the FRED website and obtain an access key (all at no cost). In the command that follows I insert my access key.
library(fredr)
fredr_set_key('c5b150d7ef18ec656ac2f4a3541dd60f')
The command to download the data is fredr which takes as
input the variable code, the units of measurement, the frequency and the
aggregation method. For wages in Italy the variable is LCWRIN01ITM661S
which reports the levels of the wage index. We want to calculate the
percentage change compared to the previous year (option
units='pc1'), with annual frequency
(frequency='a') and calculating the average value for the
year (aggregation_method='avg').
X=fredr('LCWRIN01ITM661S',
units='pc1',
frequency='a',
aggregation_method='avg')
To transform this variable into a time series of type
zoo we can use the command already seen previously (within
the quantmod package).
library(quantmod)
w=zoo(X$value,X$date)
We also download from the FRED website the value of the consumer price index for Italy: FPCPITOTLZGITA. This is already in the form of the change compared to the same period of the previous year and, therefore, does not require further processing.
X=fredr('FPCPITOTLZGITA')
inf=zoo(X$value,X$date)
Now we can plot the two variables w and inf by merging them into a single time series with the merge command.
plot(merge(w,inf,all=FALSE),screens=1,
col=c('blue','red'),lwd=2,
xlab='',ylab='Pct. change')
grid()
legend('topright',legend=c('Wages','Consumer prices'),
col=c('blue','red'),lwd=2,bty='n')
To add the dates of Italy’s exit from the ECU and its re-entry into the Euro, we give the following commands.
plot(merge(w,inf,all=FALSE),screens=1,
col=c('blue','red'),lwd=2,
xlab='',ylab='Pct. change')
grid()
legend('topright',legend=c('Wages','Consumer prices'),
col=c('blue','red'),lwd=2,bty='n')
date=as.Date(c('1992-01-01',
'1996-12-31'))
eventi=c('Exit \nECU','Re-entry \nEuro')
abline(v=date,lty=2)
text(date,25,labels=eventi,pos=1,cex=0.8)
From the Yahoo website we download three time series related to the following variables:
^GSPCEURUSD=X^TNXWe download the data starting from the day before Trump’s announcement on US tariffs.
library(quantmod)
getSymbols(c('^SPX','EURUSD=X','^TNX'),
src='yahoo',return.class='zoo',
from='2025-04-01')
## Warning: EURUSD=X contains missing values. Some functions will not work if
## objects contain missing values in the middle of the series. Consider using
## na.omit(), na.approx(), na.fill(), etc to remove or replace them.
## Warning: ^TNX contains missing values. Some functions will not work if objects
## contain missing values in the middle of the series. Consider using na.omit(),
## na.approx(), na.fill(), etc to remove or replace them.
## [1] "SPX" "EURUSD=X" "TNX"
We create the variables of interest by taking, from the downloaded data, only the adjusted closes.
borsa=SPX$SPX.Adjusted
cambio=`EURUSD=X`$`EURUSD=X.Adjusted`
tasso=TNX$TNX.Adjusted
In the case of the exchange rate we inserted backticks because the name of the variable contains an R command (the ‘=’ symbol).
To plot the three variables separately we give the following commands-
plot(borsa,col='red',lwd=2)
plot(cambio,col='orange',lwd=2)
plot(tasso,col='blue',lwd=2)
To plot them all together on the same graph it is convenient to normalize them to 1 at the start of the period. We therefore proceed to merge the variables into a single one and then calculate its normalization as already seen previously.
dati=merge(borsa,cambio,tasso,all=FALSE)
dati_norm=sweep(dati,2,dati[1],'/')
The graphical representation of the data, at this point, is obtained with the following commands.
plot(dati_norm,screens=1,col=c('red','orange','blue'),
lwd=2,xlab='',ylab='1/4/2025 = 1')
grid()
legend('topleft',legend=c('S&P 500','x USD = 1 EUR','10-year rate'),
col=c('red','orange','blue'),lwd=2,bty='n')
abline(h=1,lty=2)