ACTEX Learning: R Formula & Review Sheet
ACTEX Learning: R Formula & Review Sheet
DISTRIBUTIONS
Functions related to distributions belong to the (automatically loaded) stats package and have the form:
d<distribution>(x, <parameters>) returns the value of the PDF (f (x) or P (X = x)
p<distribution>(x, <parameters>) returns the value of the CDF (F (x)) or P (X ≤ x))
p<distribution>(x, <parameters>, lower=FALSE) returns 1 − F (x) or P (X > x)
q<distribution>(p, <parameters>) returns the min value of x for which P (X ≤ x) ≥ p (p-th quantile)
q<distribution>(p, <parameters>, lower=FALSE) returns the min value of x for which P (X > x) ≥ p
r<distribution>(n, <parameters>) returns an iid random sample of size n from the distribution
Continuous Distributions:
The parameters for Continuous Distributions are:
(a) Uniform Distribution (U (a, b)) unif(<>,a,b), dunif(<>, a, b), punif(<>, a, b), …
(b) Exponential Distribution (Exp(λ)) exp(<>, lambda)
(c) Gamma Distribution (Gamma(α, λ)) gamma(<>, alpha, lambda)
(d) Chi-square Distribution (χ2df ) chisq(<>,df)
(e) Beta Distribution (Beta(α, β)) beta(<>,alpha,beta)
(f) Normal Distribution (N (µ, σ )) 2
norm(<>,mu,sigma)
(g) Log-normal Distribution (Lognormal(µ, σ 2 )) lnorm(<>,mu,sigma)
(h) Standard Normal Distribution (N(0,1)) norm(<>)
(i) Student’s t-distribution (t(ν) ) t(<>, nu)
(j) F-Distribution (F (d1 , d2 )) f(<>, d1, d2)
Discrete Distributions:
The parameters for Discrete Distributions are:
(a) Binomial Distribution (Bin(n, p)) binom(<>, n, p)
(b) Poisson Distribution (P(λ)) pois(<>, lambda)
(c) Geometric Distribution (Geom(p)) geom(<>, p)
(d) Negative Binomial Distribution (NB(k, p)) nbinom(<>, k, p)
(e) Hypergeometric Distribution (HG(N, K, n)) hyper(<>, N, K, n)
(f) Uniform Distribution:
R does not provide built-in functions to deal with the discrete uniform distribution. Here are some alternatives:
1. Frequency Table:
Example: Frequency table for an iid sample X with Xi ∼ Bin(100, 0.2). The bottom row is the number of occurrences of
the corresponding value in the top row in the sample.
##
## 4 5 6 7 8 9 10 11 12 13 14 15 16 18
## 2 6 3 13 11 13 15 13 12 8 1 1 1 1
2. Bar chart:
Example: Bar chart for the PDF of Bin(50, 0.4):
x <- 0:50
barplot(dbinom(x, 50, 0.4), names = x)
0.06
0.00
0 4 8 13 18 23 28 33 38 43 48
3. Plots:
Example: Plot of the PDF of N (10, 22 ):
0.15
0.00
0 5 10 15 20 25 30
x−values
Example: Plot of the PDFs of N (10, 22 ) and N (20, 42 ), highlighting the µs:
0.10
0.00
0 5 10 15 20 25 30
x−values
Q-Q Plots
(a) qqnorm(x): Plots quantiles of sample data x (vertical axis) vs quantiles of a normal distribution (horizontal
axis).
(b) qqplot(sim,x): The same as above, but with generic distribution quantiles sim
(e.g. generated by qexp(seq(0, 1, 0.05), lambda))
(c) qqline(x): Adds a reference line on a Q-Q plot created with qqnorm().
Example: Q-Q plot of normal data in two different ways:
y <- rnorm(20, 50, 1) # generate a random sample
qqnorm(y) # approach 1: qqnorm
qqline(y)
sim <- qnorm(seq(0, 1, 0.01), 0, 1) # generate quantiles
qqplot(sim, y) # approach 2: qqplot
Sample Quantiles
52
50
48
−2 −1 0 1 2
Theoretical Quantiles
52
50
y
48
sim
X̄ ∼ N (18, 0.144)
N <- 30
p <- 0.6
set.seed(30) # setting a seed makes the code results repeatable!
xbar <- rep(0,1000) # initialize a sequence [1, 2, 3, ..., 1000]
for (i in 1:1000) {
x <- rbinom(50, N, p) # generate a sample of size 50 from Bin(30, 0.6)
xbar[i] <- mean(x) # replace each value of the sequence by the sample mean
}
hist(xbar, prob = TRUE, xlab = "Sample means")
rng <- range(xbar) # returns a vector with [min(xbar), max(xbar)]
xvals <- seq(rng[0], rng[1], 0.001)
lines(xvals, dnorm(xvals, N * p, sqrt((N * p * (1-p)) / 50)), col = "red")
Histogram of xbar
1.2
Density
0.6
0.0
Sample means
DATA ANALYSIS
Scatter Plots:
Correlation:
Correlation Test:
<name>.test(<data>,
alternative = <>, # can be "two.sided", "less" or "greater"
conf.level = 0.95,
mu = <>) # depends on the parameter in study;
# when set, this it becomes the Null Hypothesis
Example:
## [1] 1.113842e-43
Example: Output from calling the t.test function on a normal sample with a probable µ = 2
##
## One Sample t-test
##
## data: x
## t = 44.174, df = 49, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 2
## 95 percent confidence interval:
## 19.06296 20.68939
## sample estimates:
## mean of x
## 19.87618
3. Variance Ratio:
Chi-squared tests:
1. Goodness-of-fit (only HT makes sense; H0 is the hypothesis that the data is generated from a multinomial distribution
with the ps as probabilities):
chisq.test(x, p) # HT
# x is a vector of integers (the counts of each class)
# p is the probabilities of each class
Example: A man sitting in his balcony has spotted a number of birds belonging to one of six species.
The exact classification is given below:
Species 1 2 3 4 5 6
Frequency 8 10 13 9 11 14
Test at 5% level of significance whether or not the data are compatible with the assumption that the particular area is
visited by the same proportion of birds belonging to these six species in the population. (Goodness-of-fit test)
# Using the chi-squared test:
obs <- c(8, 10, 13, 9, 11, 14)
n <- length(obs)
ep <- rep(1/n, n) # a vector c(1/n, 1/n, ..., 1/n)
pval1 <- chisq.test(obs, p = ep)$p.value
pval1
## [1] 0.7799664
## [1] 0.7799664
Since the p-value is greater than 0.05, we have no reason to reject the hypothesis that the six species occur with the same
frequency.
LINEAR REGRESSION
Linear Regression Models:
summary(model1)
##
## Call:
## lm(formula = Y ~ X)
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.5506 -0.8937 -0.1579 0.9268 3.1274
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 59.5070 2.1692 27.43 <2e-16 ***
## X 20.1292 0.1045 192.53 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.639 on 48 degrees of freedom
## Multiple R-squared: 0.9987,Adjusted R-squared: 0.9987
## F-statistic: 3.707e+04 on 1 and 48 DF, p-value: < 2.2e-16
Since the p-value is less than 5%, we should reject H0 (that all coefficients except the intercept are zero).
The coefficients could have also been obtained via model1$coef or coef(model1).
Using models for prediction and Confidence Interval for Mean and Individual Response:
## 1
## 663.3824
20 20
Residuals
1
−1
47 47
−4
19
−3
19
## [1] 34.66667
## 2.5 % 97.5 %
## (Intercept) 3.039784 5.960216
## popB -1.065058 3.065058
## popC 1.934942 6.065058
Form Model
model <- lm(Y ~ X1 + X2 + X3) Y = a + b1 · X1 + b2 · X2 + b3 · X3
model <- lm(Y ~ X1 * X2) Y = a + b1 · X1 + b2 · X2 + b12 · X1 · X2
model <- lm(Y ~ X1 + X2 + X1:X2) Y = a + b1 · X1 + b2 · X2 + b12 · X1 · X2
model <- lm(Y ~ I(X1^2)) Y = a + b1 · X12 ; the I(<arg>) makes <arg> “literal”
##
## Call:
## lm(formula = Y ~ X1 + X2)
##
## Residuals:
## Min 1Q Median 3Q Max
## -10.6062 -2.2655 0.2998 2.6385 9.4370
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 43.4326 4.2955 10.11 <2e-16 ***
## X1 19.9993 0.2083 96.00 <2e-16 ***
## X2 -0.1355 0.1011 -1.34 0.183
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.895 on 97 degrees of freedom
## Multiple R-squared: 0.9896,Adjusted R-squared: 0.9894
## F-statistic: 4632 on 2 and 97 DF, p-value: < 2.2e-16
ANOVA Table:
anova(model1)
## 2.5 % 97.5 %
## (Intercept) 34.9071989 51.95802047
## X1 19.5858137 20.41275538
## X2 -0.3362104 0.06521903
Standardized residuals
Residuals vs Fitted Normal Q−Q
10
75 80 75 80
2
Residuals
0
−10
−2
68 68
##
## Call: glm(formula = Y ~ age + vehicle_type, family = poisson(), data = DF)
##
## Coefficients:
## (Intercept) age vehicle_type
## -2.00875 0.05106 0.68335
##
## Degrees of Freedom: 999 Total (i.e. Null); 997 Residual
## Null Deviance: 2583
## Residual Deviance: 1115 AIC: 3228
confint(g, par = c(1, 2, 3), level = 0.90) # 90% confidence interval for all 3 parameters
## 5 % 95 %
## (Intercept) -2.16265206 -1.85726127
## age 0.04844901 0.05368993
## vehicle_type 0.61529167 0.75160250
## 1 2
## 0.2062803 -0.4770718
6
2 4 6
819 819
Residuals
514 514
259
4
259
2
−2
−2
−1.0 0.0 0.5 1.0 1.5 2.0 −3 −2 −1 0 1 2 3
Model Comparison:
## [1] 3500.063
g$aic
## [1] 3227.675
## [1] 2.208667
where: λ̂Prior = β, the expected value of the prior, as in the example above; λ̂Individual = and Z = is the
P
α xi n
n n+β
Credibility Factor.
set.seed(100)
n <- 20
Z <- n / (n + 4)
## [1] 2.208667
## A B C D E
## 1662.853 3083.215 2923.090 5129.247 5768.262
5000
Entity Mean
Future Premium
Value
2000
A B C D E
Entity
Model 2: For this model, include a second dataframe consisting of policy volume.
## A B C D E
## 180.9165 337.8925 725.0477 687.0478 762.1102
set.seed(10)
df <- rnorm(1000, c(2, 10), c(1, 2))
data <- matrix(df, 500, 2)
10
5
0
0 5 10 15
data[,1]
BOOTSTRAP INFERENCE
Parametric bootstrap:
Example: X is a sample of size 300 from a normal distribution N (10, 52 ). Let’s compute the bootstrap empirical
distribution of X̄:
## 2.5% 97.5%
## 9.744772 10.855255
Non-parametric bootstrap:
Example: X is now a sample of size 300 from an unknown distribution; let’s compute the bootstrap empirical distribution
of X̄:
## 2.5% 97.5%
## 9.731208 10.866606
for (i in 1:10000) {
p <- sample(index, n1, replace = F) # sample n1 indexes out of the n1 + n2
diff[i] <- mean(result[p]) - mean(result[-p]) # compute this sample means differences
}
obs <- abs(mean(X1) - mean(X2)) # sample means differences
length(diff[abs(diff) >= obs]) / length(diff) # probability that a permutation sample has
# greater diff than the observed one(i.e. a p-value!)
Permutation test: Example: X1 and X2 are samples: we’re interested in finding out whether or not the they come
from the same population via Permutation Testing the sample means differences.
X1 <- rnorm(10, 10, 5) # generate a normal sample X1; needs to be very small
X2 <- rnorm(10, 2, 5) # generate a normal sample X2; needs to be very small
p <- combn(index, n1) # generate all combinations; explodes with n1 and n2!
n <- choose(n1 + n2, n1) # combinations n1 + n2 choose n1
diff <- rep(0, n) # initialize all combinations
for (i in 1:n) {
diff[i] <- mean(result[p[,i]]) - mean(result[-p[,i]]) # compute this sample means differences
}
#P-value
obs <- abs(mean(X1) - mean(X2)) # sample means differences
length(diff[abs(diff) >= obs]) / length(diff) # probability that a permutation sample has
# greater diff than the observed one(i.e. a p-value!)
CREATING FUNCTIONS
Syntax:
Example: Creating pdf, cdf and random sampling function for Pareto distribution X ∼ Pareto(a, l).
## 2 * x + 3
Numerical Integration:
Example: Estimate 0 2x + 3dx
R1
## [1] 4
LOSS DISTRIBUTION
Generating Maximum Likelihood Estimates (MLE) and analysing the fit:
Example: Use MLE to estimate the parameters of a normally distributed sample:
Histogram of sample
0.08
Density
0.04
0.00
−5 0 5 10 15 20 25
sample
## shape rate
## 19.98918983 0.50248312
## ( 0.62686916) ( 0.01595715)
X <- rgamma(2000, a, l)
qqplot(X, ozone, ylab = "Sample quantile", ylim = c(0,200))
abline(0, 1, col = "blue")
200
Sample quantile
100
0
sx
REINSURANCE
Proportional Reinsurance:
Example: Suppose Insurance claims follow a distribution LogN(5, 2) and the value of α is 75% (that is, the reinsurer pays
25% of the claims). How does this affect the payments?
set.seed(50)
claim <- rlnorm(1000, 5, 2)
a <- 0.75
## [1] -25
## [1] -25
set.seed(10)
rpareto <- function(n, a, l) {
l * ((1 - runif(n))^(-1/a) - 1)
}
claim <- rpareto(10000, 3, 600)
m <- 1000
paid.insurance <- pmin(claim, m)
paid.reinsurer <- pmax(0, claim - m)
(mean(paid.insurance) - mean(claim)) / mean(claim) * 100
## [1] -15.14916
## [1] -48.57061
Inflation Case:
Example: Assume an inflation rate of 12% per annum. Assess the impact of inflation on the mean and standard deviation
of claims paid by insurance and reinsurer, given that the retention limit M = 1000.
set.seed(10)
rpareto <- function(n, a, l) {
l * ((1 - runif(n))^(-1/a) - 1)
}
claim <- rpareto(10000, 3, 600)
m <- 1000
paid.insurance <- pmin(claim, m)
paid.reinsurer <- pmax(claim - m, 0)
i <- 0.12
k <- (1+i)
paid.insurance.i <- pmin(k * claim, m)
paid.reinsurer.i <- pmax(k*claim - m, 0)
## [1] 9.299076
## [1] 27.12794
RISK MODELS
Collective Risk Models:
Example: Estimate the distribution of
set.seed(10)
## [1] 0.967
set.seed(10)
S <- rep(0, 10000)
for (j in 1:10000) {
Y <- rgamma(300, shape = 220, rate = 0.75)
Z <- rgamma(900, shape = 310, rate = 0.45)
T <- c(Y, Z)
DY <- rbinom(300, 1, 0.002)
DZ <- rbinom(900, 1, 0.001)
D <- c(DY, DZ)
S[j] <- sum(T * D)
}
hist(S)
Histogram of S
3500
Frequency
1500
0
SURVIVAL MODELS
Creating a function for Makeham’s Law:
Example: Assuming Makeham’s Law, µ(x) = A + B ∗ C x , we will compute the survival
Z t
t px = Sx (t) = P [Tx > t] = exp − µ(x + s)ds
0
first using first principles, then numerically. After that we compute the expectation e̊x and the curtate expectation ex .
p <- list(A = 0.00004, B = 0.0000025, C = 1.1) # store the model parameters in a list
mu <- function(x) {
p$A + p$B * p$C^x
}
tpx1(35, 10)
## [1] 0.9984264
tpx2(35, 10)
## [1] 0.9984264
## [1] 54.75777
## [1] 54.2578
The flexsurv library: The (automatically loaded) stats package does not include functions to deal with the Gompertz
distribution. That’s where the flexsurv function comes in.
library(flexsurv)
x <- 30
t <- 25
Sxt <- pgompertz(x+t, shape, rate, lower.tail = FALSE) # S(x + t)
Sx <- pgompertz(x, shape, rate, lower.tail = FALSE) # S(x)
tpx <- Sxt / Sx
tpx
## [1] 0.3473415
## [1] 0.001244782
4
2
0
30 40 50 60 70 80 90 100
Ages
## [1] 0.3145845
## [1] 0.3145845
mu <- function(x) {
p$B * p$C^x
}
mu(55)
## [1] 0.2201512
## [1] 0.2201512
integrate(mu, 0, 45)$value
## [1] 0.1341624
## [1] 0.1341624
Survival Distributions:
1. Exponential distribution: Tx ∼ Exp(0.075)
# P(Tx <= 30)
lambda <- 0.075
pexp(30, lambda)
## [1] 0.8946008
## [1] 0.6268969
log_PL <- 0
for (i in sorted_event_indices) {
risk_set <- which(df$T >= df$T[i])
new.term <- beta * df$X[i] - log(sum(exp(beta * df$X[risk_set])))
log_PL <- log_PL + new.term
}
-log_PL
}
library(survival)
data <- data.frame(X = c(0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1), # Covariate: 1 if Hospital A, 0 if B
T = c(60, 32, 60, 60, 60, 4, 18, 60, 9, 31, 53, 17), # Time of death in months
C = c(0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1)) # 0 if censored, 1 if death
## Call:
## coxph(formula = surv_object ~ X, data = data)
##
## n= 12, number of events= 7
##
## coef exp(coef) se(coef) z Pr(>|z|)
## X 2.118 8.318 1.092 1.939 0.0525 .
## ---
## Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
##
## exp(coef) exp(-coef) lower .95 upper .95
## X 8.318 0.1202 0.9776 70.77
##
## Concordance= 0.741 (se = 0.068 )
## Likelihood ratio test= 5.54 on 1 df, p=0.02
## Wald test = 3.76 on 1 df, p=0.05
Nelson-Aalen:
# data is the same as in the previous example!
Survival Probabilities
0.95
0.95
0.85
0.85
0 5 10 15 20 25 0 5 10 15 20 25
library(survival)
#Generating estimates
survival.km <- survfit(surv.obj ~ 1, conf.type = "plain")
survival.na <- survfit(surv.obj ~ 1, conf.type = "plain", stype = 2)
KM
NA
0.8
S(t)
0.4
0.0
0 2 4 6 8
time
MORTALITY RATES
Example: Compute µ70 for the insured population in this example, between 2013 and 2017. In this case, each person is
exposed while they are
• alive
• insured
pop <- data$DEATH > d.0 & data$DEATH < d.1 # consider only deaths in the study period
age <- data$DEATH[pop] - data$BIRTH[pop] # age at death
d <- age[age >= 70 & age < 71] # age of death is 70 years old
mu70 <- length(d) / ecx
mu70 # deaths per person.year
## [1] 0.06773931
MARKOV CHAINS
Markov Chain library: Install (using install.packages(<>)) and load (using library(<>) the package markovchain
before running this code.
## [1] TRUE
period(mc)
## [1] 1
## S1 S2
## [1,] 0.2105263 0.7894737
steadyStates(mc)
## S1 S2
## [1,] 0.2105263 0.7894737
Premium Calculations:
Example: Computing premiums using first principles.
## [,1] [,2]
## [1,] 0.10 0.90
## [2,] 0.05 0.95
## [1] 350.2216
## [,1]
## [1,] 350.2216
Sampling: Example: Sampling from a Markov Chain and fitting a Markov Chain from a sequence of states, using the
markovchain library.
## [,1] [,2]
## [1,] 0.35 0.65
## [2,] 0.80 0.20
#Sampling
#rmarkovchain(<n>,<mc>,t0="start state",include.t0=TRUE)
set.seed(10)
data <- rmarkovchain(5, mc, t0 = "20%", include.t0 = T) # generates a vector/sequence of states
data
## MLE Fit
## A 2 - dimensional discrete Markov Chain defined by the following states:
## 0%, 20%
## The transition matrix (by rows) is defined as follows:
## 0% 20%
## 0% 0.5384615 0.4615385
## 20% 0.8571429 0.1428571
px <- function(x) {
matrix(c((1 - prob_01(x)), prob_01(x), 1 - prob_11(x), prob_11(x)), 2, 2, byrow = T)
}
# starting from the first state at 35 years old, these are the state probabilities 10 years later:
fx(35, 10, c(1, 0))
## [,1] [,2]
## [1,] 0.1606768 0.8393232
## [1] 0.05833333
Example: Now we’re interested in the same probability, but over 30 years (we already computed it for one month!)
# ph and states as in the example above
library("markovchain")
markov_chain <- new("markovchain", transitionMatrix = ph, states = states)
markov_chain ^ (12 * 30)
library(markovchain)
set.seed(10)
sims <- rmarkovchain(1000, markov, include.t0 = T)
head(sims)
## [1] "state 3" "state 3" "state 3" "state 3" "state 3" "state 3"
## [1] "state 3" "state 2" "state 1" "state 3" "state 2" "state 1"
ljs = -diag(GM) # the diagonal values of the generator matrix are the
waiting_times <- rexp(1000, ljs[sims2]) # rate parameters of the waiting times (exp.) distributions.
head(waiting_time)
Time-Inhomogeneous: Example: Simulating a time-inhomogenous Markov jump process. We use the approximation
P (t, t + h) ≈ I + h · GM(t)
Pts(1, 2, 1/10000)
TIME SERIES
Simulating a Stationary Time Series
set.seed(10)
yt <- arima.sim(n = 10, list(ar = c(0.6, -0.2), ma = 0.3), sd = 5)
yt
## Time Series:
## Start = 1
## End = 10
## Frequency = 1
## [1] 8.3867410 4.6225682 5.6760659 7.6692436 5.0251545 -3.1594544
## [7] -5.3088712 1.7814489 5.9338181 0.9469157
set.seed(50)
N <- 10
et <- rnorm(N, mean = 0, sd = 5)
xt <- cumsum(et)
Using the ACF to determine if the series needs differencing to become stationary:
N <- 100
et <- rnorm(n, mean = 0, sd = 5)
xt <- cumsum(et)
xt
0.8
0.4
0.0
0 5 10 15 20 25 30
Lag
Phillips-Perron test:
PP.test(xt) # H0 is the hypothesis that the series has a unit root (and therefore is not stationary).
##
## Phillips-Perron Unit Root Test
##
## data: xt
## Dickey-Fuller = -1.9202, Truncation lag parameter = 7, p-value = 0.6121
# since the p-value is greater than the significance level of 0.05, we don't reject H0.
# take differences:
zt <- diff(xt, lag = 1, differences = 1)
acf(zt, main = "Sample ACF of differenced series")
0.2
−0.4
0 5 10 15
Lag
PP.test(zt)
##
## Phillips-Perron Unit Root Test
##
## data: zt
## Dickey-Fuller = -7.2067, Truncation lag parameter = 3, p-value = 0.01
This time, H0 should be rejected; no further differencing seems to be needed. This is also visible in the ACF plot – the
decay of autocorrelations is very swift.
A heuristic to pick the order of differencing is to take the point where the variance of the series goes up!
ut <- xt
for (i in 0:4) {
print(paste0("order = ", i, ", var = ", var(ut))) # paste0 concatenates strings!
ut <- diff(ut, lag = 1, differences = 1)
}
Identifying and removing trends using linear least-squares: Example: Identifying the trend
N <- 100
yt <- arima.sim(n = N, list(ar = c(0.6, -0.2), ma = 0.3), sd = 5)
xt <- 10 + 5 * (1:N) + yt
ts.plot(xt)
t <- seq(1:N)
trend <- lm(xt ~ t)
lines(t, trend$fitted.values, type = "l", col = "blue")
200 400
xt
0 20 40 60 80 100
Time
10
0
−15
0 20 40 60 80 100
Time
3000
ldeaths
1500
Time
−0.5
Lag Frequency
bandwidth = 0.0481
0.5
ldeaths
ACF
−0.5
1500
Time Lag
0.5
0
ACF
dif
−1500
−0.5
1975 1976 1977 1978 1979 1980 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4
Time Lag
3000
ldeaths
ldeaths
1500
1500
Time Time
Fitting a time series model: For MA(q) models, we determine the order by looking at the ACF and counting how many
lags it takes to ”cut off”, and confirming that the ACF ”tails off” (decays exponentially).
For AR(p) models, we determine the order by looking at the PACF and counting how many lags it takes to cut off, and
confirming that the ACF tails off.
0.8
0.2
2
Partial ACF
0.0
0.4
ACF
0
xt
−0.2
0.0
−2
−0.4
−0.6
−4
−0.4
0 20 40 60 80 100 0 5 10 15 20 5 10 15 20
Example: Fitting an ARIMA model (i.e. determining the coefficients): the lower the AIC the better!
##
## Call:
## arima(x = xt, order = c(0, 0, 3))
##
## Coefficients:
## ma1 ma2 ma3 intercept
## -0.1770 -0.2840 0.1213 0.2499
## s.e. 0.1008 0.1186 0.1215 0.1402
##
## sigma^2 estimated as 4.453: log likelihood = -216.68, aic = 443.37
## [1] 440.5388
Forecasting Example
4
2
Data
−2
0 20 40 60 80 100 120
Time
Exponential Smoothing:
set.seed(50)
N <- 100
etx <- rnorm(N, mean = 0, sd = 5)
xt <- cumsum(etx)
xt <- ts(xt, start=c(2020, 1), frequency = 12)
HW <- HoltWinters(xt, alpha = 0.7, beta = F, gamma = F)
HW
find.cointegrated <- function(x) { # the lowest the p-value the most likely
comb <- xt*x[1] + yt*x[2] # for the linear combination to be stationary
PP.test(comb)$p.value
}
X$estimate
# Confirm stationarity.
zt <- X$estimate[1]*xt + X$estimate[2]*yt
PP.test(zt)
##
## Phillips-Perron Unit Root Test
##
## data: zt
## Dickey-Fuller = -4.0434, Truncation lag parameter = 2, p-value =
## 0.02174
# Both values have absolute value less than 1, so the process is stationary.