# aggiornamento 24 novembre 2003
# source("c:/discod/didattica/dispense-software/librerie/sse.lib")
monthplot=function(x, type = "l", labels, xlab = "", ylab = "", ...)
{
if(length(dim(x)))
stop("This implementation is only for univariate time series"
)
old.opts = options(warn = -1)
on.exit(options(old.opts))
if(!(type == "l" || type == "h"))
stop(paste("type is \"", type,
"\", it must be \"l\" or \"h\"", sep = ""))
if(ylab=="") ylab=deparse(substitute(x))
x = as.ts(x)
f = frequency(x)
cx = cycle(x)
m = tapply(x, cx, mean)
if(cx[1] != 1 || cx[length(x)] != f) {
x = ts(c(rep(NA, cx[1] - 1), x, rep(NA, f - cx[
length(x)])), start = start(x, format = T)[1],
end = c(end(x, format = T)[1], f), frequency
= f)
cx = cycle(x)
}
i = order(cx)
n = length(x)
if(missing(labels))
labels = if(f == 12) c("Jan", "Feb", "Mar", "Apr",
"May", "Jun", "Jul", "Aug", "Sep",
"Oct", "Nov", "Dec") else if(f == 4)
c("First", "Second", "Third", "Fourth")
else 1:f
if(length(labels) != f)
stop(paste("There must be", f, "labels"))
p = n/f
hx = seq(1, n, by = p) + (0:(f - 1))
hy = rep(m, rep(2, length(m)))
X = as.vector(outer(0:(p - 1), hx, "+"))
plot(c(1, n + f), range(x[!is.na(x)]), type = "n", axes = F,
xlab = xlab, ylab = ylab, ...)
dotdot = list(...)
ddttl = match(c("main", "sub", "axes", "ylim"), names(dotdot),
nomatch = 0)
ddttl = ddttl[ddttl != 0]
add.axes = T
if(length(ddttl)) {
if(any(names(dotdot) == "axes"))
add.axes = dotdot$axes
dotdot = dotdot[ - ddttl]
}
if(type == "l")
for(j in 1:f)
do.call("lines", c(list(hx[j]:(hx[j] + p - 1),
x[i][((j - 1) * p + 1):(j * p)]),
dotdot))
else if(type == "h")
do.call("segments", c(list(X, x[i], X, m[cx][i]),
dotdot))
do.call("segments", c(list(hx, m, hx + p, m), dotdot))
if(add.axes) {
box()
axis(2)
axis(1, at = hx + p/2, labels = labels)
}
invisible()
}
#arma.sim.old = function(n, ar = NULL, ma = NULL, sigma = 1.0)
#{
# x = ts(rnorm(n+100, 0, sigma^2), start = -99)
# if(length(ma)) x = filter(x, ma, sides=1)
# if(length(ar)) x = filter(x, ar, method="recursive")
# as.ts(x[-(1:100)])
#}
# La funzione precedente (suggerita nella pagina di help di R per la
# funzione filter) non genera correttamente processi con componenti a
# media mobile. La seguente funzione invece si comporta bene.
arma.sim = function(n, ar = NULL, ma = NULL, sigma = 1.0)
{
x = ts(rnorm(n+100, 0, sigma), start = -99)
if(length(ma)) x = filter(x, c(1,ma), sides=1)
if(length(ar)) x = filter(x, ar, method="recursive")
as.ts(x[-(1:100)])
}
arima.diag=function(object,gof.lag=10, max.lag=NULL)
{
data = eval(parse(text = object$series))
residuals=object$resid
n.par=length(object$coef)
n = length(residuals)
if ( is.null(max.lag) )
max.lag = max(gof.lag + n.par + 1, 10 * log10(n))
cor = acf(residuals, lag.max = max.lag,plot=FALSE)
p.value=NULL
for (lag in 1:gof.lag) {
obs = cor$acf[2:(lag + 1)]
STATISTIC = n * (n + 2) * sum(1/seq(n - 1, n - lag) * obs^2)
p.value =c(p.value, 1 - pchisq(STATISTIC, lag))
}
par(mfrow=c(3,1))
plot(residuals)
plot.acf(cor)
plot(1:gof.lag,p.value,xlab="lag",ylab="pvalue")
abline(h=0.05,lty=2,col="red")
par(mfrow=c(1,1))
}
# rgams
#
# genera valori da funzione gamma segnata, con funzione di densita'
#
# f(x) = \frac12 \frac{\lambda^r}{\Gamma(r)} |x|^{r-1} \exp\{-\lambda |x|\} ,
#
# dove lambda e' il parametro di scala (scale) e r e' il parametro di
# forma (shape). I valori vengono ottenuti generando prima n valori da
# una gamma e poi cambiandoli di segno con probabilita' 1/2.
# Il numero di valori generati e' n.
rgams=function(n,shape,scale=1)
{
return(rgamma(200,shape,1/scale)*(1-2*(runif(200)>0.5)))
}
# TACF - di Alfredo Barbieri e Alessio Boaretto
valpsi= function (r,p,q,phi,theta) {
psiparzj[1]<=1
arretrapsiparzj=function (p) {
for (i in 0:(p-1)) psiparzj[[i+1]]<=psiparzj[[i+2]]
}
if (r==0) psi=1
else {
if (r>q) psi=0
else psi=theta[r]
if (r>p) {
if (p>0) arretrapsiparzj(p)
if (p>0) for (l in 1:p) psi=psi-phi[l]*psiparzj[[p-l+1]]
r=p
}
else {
for (l in 0:(r-1)) psi=psi-phi[r-l]*psiparzj[[l+1]]
}
}
psiparzj[r+1]<=psi
return (psi)
}
durbinlevinson=function (gamma,lag.max) {
phikk=array(0,lag.max)
phidl=array(0,lag.max)
phidl1=array(0,lag.max)
v=array(0,lag.max)
sommatoria=0
v[1]=gamma[1]
phidl[1]=gamma[2]/gamma[1]
phikk[1]=phidl[1]
v[2]=v[1]*(1-phidl[1]^2)
if (lag.max>1) for (i in 2:lag.max) {
for (j in 1:i-1) phidl1[j]=phidl[j]
sommatoria=0
for (j in 1:i) sommatoria=sommatoria+phidl1[j]*gamma[abs(i-j+1)]
phidl[i]=(gamma[i+1]-sommatoria)/v[i]
phikk[i]=phidl[i]
for (j in 1:i-1) phidl[j]=phidl1[j]-phidl[i]*phidl1[i-j]
v[i+1]=v[i]*(1-phidl[i]^2)
}
return (phikk)
}
tacf=function (p=0,q=0,phi=0,theta=0,lag.max=20,graphics=0,wn.var=1) {
if(p>0) {
repeat {
if ((phi[p]!="NA") && (phi[p]!=0)) break
p=p-1
}
}
if(q>0) {
repeat {
if ((theta[q]!="NA") && (theta[q]!=0)) break
q=q-1
}
}
if (p>0) {
if (sum(Mod(polyroot(c(1,-phi[1:p])))>1)
0) for (i in p:1) phi[i+1]=-phi[i]
if (q>0) for (i in q:1) theta[i+1]=theta[i]
phi[1]=1
theta[1]=1
b=array(0,m+1)
A=array(0,dim=c(m+1,m+1))
for (k in 0:m) {
somma=0
if (k<=q) for (j in k:q) somma=somma+theta[j+1]*psi[j-k+1]
b[k+1]=somma
}
for (i in 1:(m+1)) {
for (j in 1:(m+1)) {
somma=0
if (j==1) {
if (i<=(p+1)) somma=phi[i]
}
else {
if ((i+j-2)<=p) somma=phi[i+j-1]
if ((i-j)<=p && (i-j)>=0) somma=somma+phi[i-j+1]
}
A[i,j]=somma
}
}
primigamma=solve(A,b)
for (i in 1:(m+1)) gamma[i]=primigamma[i]
if (p>0) for (i in 1:p) phi[i]=-phi[i+1]
if (q>0) for (i in 1:q) theta[i]=theta[i+1]
if ((m+1)0) for (j in 1:p) dump=dump+phi[j]*gamma[k-j+1]
gamma[k+1]=dump
}
k=1
repeat {
facr[k]=gamma[k+1]/gamma[1]
k=k+1
if (k>lag.max) break
}
phikk=durbinlevinson (gamma,lag.max)
acf=formatC(facr[1:lag.max],digits=7,format="f")
pacf=formatC(phikk[1:lag.max],digits=7,format="f")
acvf=formatC(gamma[2:(lag.max+1)]*wn.var,digits=7,format="f")
var=formatC(gamma[1]*wn.var,digits=7,format="f")
if (graphics==1) {
# par(mfrow=c(2,1), mai=c(0.5,0.5,0.5,0.5))
plot(acf,type="h", ylab="acf")
abline (h=0)
plot(pacf,type="h", ylab="pacf")
abline (h=0)
}
else return (acf,pacf,var,acvf)
}
# filterp e' una versione semplificata di filter che serve ad applicare
# filtri periodici. La funzione e' lenta perche', a differenza di filter,
# usa cicli for e non fa riferimento a codice C esterno. La funzione
# filterp e' diversa da filter anche per il modo con cui tratta i
# valori iniziali.
filterp=function(e, filt, period, method = "convolution")
{
n=length(e)
lf<=length(filt)
x=rep(-1,n) # inizializzazione del vettore che conterra' la serie filtrata
x[1:(lf*period)]=e[1:(lf*period)] # valori iniziali
if (method == "recursive"){
for (i in (lf*period+1):n){
x[i]=e[i]
for (j in 1:lf)
x[i]=x[i]+filt[j]*x[i-j*period]
}
}
else{
for (i in (lf*period+1):n){
x[i]=e[i]
for (j in 1:lf)
x[i]=x[i]+filt[j]*e[i-j*period]
}
}
return(x)
}
arma.sim.p = function(n, ar=NULL, ma=NULL, sar = NULL, sam = NULL, period = 12, sigma = 1.0)
{
if (length(ar) || length(ma))
x = arma.sim(n+100,ar,ma,sigma)
else
x = ts(rnorm(n+100, 0, sigma), start = -99)
if(length(sam)) x = filterp(x, sam, period)
if(length(sar)) x = filterp(x, sar, period, method="recursive")
as.ts(x[-(1:100)])
}
aic.comp = function(x=NULL,max.p=NULL,max.q=NULL,d=NULL)
{
mat.aic=NULL # inizializziamo la matrice che conterra' i risultati
for (p in 0:max.p){
for(q in 0:max.q){
if (p>0 | q>0){
fit=arima0(x,order=c(p,d,q))
mat.aic=rbind(mat.aic,c(fit$aic,p,d,q))
}
}
}
return(mat.aic)
}
# pierce.test
#
# effettua il test di pierce sulla stagionalità dei residui
pierce.test=function(x=NULL, m=NULL, s=NULL, para=NULL)
{
kk=acf(x,m*s, plot=FALSE)
n=length(x)
statistics=0
for (i in 1:m)
{
statistics=statistics+(1/(n-(i*s)))*kk$acf[(i*s)+1]^2
}
statistics=statistics*n*(n+2)
p.value=1-pchisq(statistics, m-para)
return(list(statistics=statistics, p.value=p.value))
}
automatic=function(x=NULL,pmax=NULL,qmax=NULL,c=sqrt(2))
{
n=length(x)
pmax=3
qmax=3
aic2=matrix(1,pmax+1,qmax+1)
aic=matrix(1,pmax+1,qmax+1)
scc=matrix(1,pmax+1,qmax+1)
hqc=matrix(1,pmax+1,qmax+1)
for (i in 0:pmax)
{
for (j in 0:qmax)
{
x.modello=arima(x,order=c(i,0,j),include.mean=T)
verosim=x.modello$loglik
varianza=x.modello$sigma2
aic2[i+1,j+1]=(-2*verosim)+2*(i+j)
aic[i+1,j+1]=log(varianza)+(2*(i+j))/n
scc[i+1,j+1]=log(varianza)+(i+j)*(log(n)/n)
hqc[i+1,j+1]=log(varianza)+(i+j)*c*log(log(n))/n
# fpe[i+1,j+1]=(N+i)/(N-i)
}
}
return(aic,aic2,scc,hqc)
}
Ljung.Box= function (x, lag = 15, param=1)
{
if (NCOL(x) > 1)
stop ("x is not a vector or univariate time series")
DNAME = deparse(substitute(x))
cor = acf (x, lag.max = lag, plot = FALSE)
n = length(x)
PARAMETER = lag-param
obs = cor$acf[2:(lag+1)]
STATISTIC = n*(n+2)*sum((1/seq(n-1,n-lag))*obs^2)
PVAL = 1-pchisq(STATISTIC,lag-param)
return(list(statistic=STATISTIC,
gdl = PARAMETER,
pvalue = PVAL))
}
asimm=function(x)
{
n=length(x)
m3=sum((x-mean(x))^3)/n
sigma3=(sd(x))^3
return(m3/sigma3)
}
curtosi=function(x=NULL)
{
n=length(x)
m4=sum((x-mean(x))^4)/n
sigma4=(sd(x))^4
return(m4/sigma4)
}
stat.mod=function(fit.y,maxlag=15,ordini=0)
{
Coef=fit.y$coef
Std.Err=sqrt(diag(fit.y$var.coef))
tstat=fit.y$coef/sqrt(diag(fit.y$var.coef))
pval=2*pnorm(abs(tstat),lower.tail=F)
tabella=data.frame(Coef,Std.Err,tstat,pval)
sigma2=fit.y$sigma2
names(sigma2)="sigma2"
AIC=fit.y$aic
names(AIC)="AIC"
loglik=fit.y$loglik
names(loglik)="loglik"
cc1=Ljung.Box(fit.y$resid,maxlag,ordini)
riga0="-------------- Stime dei parametri -----------"
names(riga0)=" "
riga="-----------------------------------------------"
names(riga)=" "
print(riga0, quote=F)
print(tabella)
print(riga, quote=F)
riga2="-------------Test di Ljung-Box ---------------"
names(riga2)=" "
print(c(sigma2,AIC,loglik))
print(riga2, quote=F)
print(t(cc1))
}
prevedi=function(fit.x,k=10,sig=0.95)
{
pre=predict(fit.x,k)
p=pre$pred[1:k]
se=pre$pred[1:k]
limsup=p+qnorm(0.5-sig/2)*se
liminf=p-qnorm(0.5-sig/2)*se
prev=list(p,liminf,limsup,se)
names(prev)=c("p","inf","sup","se")
return(prev)
}
cfs=function(x,maxlag=24,new=F)
{
if (new==T)
{
x11(width=8,height=8)
par(mfrow=c(2,1),mai=c(0.8,0.8,0.8,0.8))
#par(bg="cornsilk")
}
acf(x,maxlag, na.action=na.pass)
pacf(x,maxlag, na.action=na.pass)
}
plotta=function(x)
{
plot(x,type="l")
}
rw.sim=function(n=300, drift=0, eps.sd=1, plot=t)
{
y=rep(0,n+50)
eps=rnorm(n+50,mean=0,sd=eps.sd)
y[1]=rnorm(1)
for (i in 2:(n+50)) y[i]=drift+y[i-1]+eps[i]
if (plot==T) plot(y[51:n+50], type="l")
return(y[51:n+50])
}
intconf.coef=function(mod, alpha=0.95)
{
m=length(mod$coef)
mat=matrix(0,nrow=m,ncol=3)
nomi=c("estimate", "lim.inf", "lim.sup")
dimnames(mat)=list(NULL,nomi)
mat[,1]=mod$coef
mat[,2]=mod$coef+qnorm((1-alpha)/2)*sqrt(diag(mod$var.coef))
mat[,3]=mod$coef-qnorm((1-alpha)/2)*sqrt(diag(mod$var.coef))
return(mat)
}
Ljung.Box.2=function(x, maxlag=20, par=0, all=TRUE)
{
if (all==TRUE) {
LB=matrix(0,nrow=maxlag, ncol=3)
dimnames(LB)=list(NULL, c("statistic", "gdl","pvalue"))
for (i in (par+1): maxlag) {
lbi=Ljung.Box(x, lag=i, par=par)
LB[i,]=c(round(lbi$statistic,2), lbi$gdl, lbi$pvalue)
}
plot(LB[,3], type="h", lwd=4, ylim=c(0,1), main="Ljung-Box test", ylab="p-value", xlab="k")
abline(h=0.05, lty=2, col="red")
abline(h=0)
}
if (all==FALSE) LB=Ljung.Box(x, lag=maxlag, par=par)
return(LB)
}
make.dummy <- function(n, freq=12, start=1)
{
dv=matrix(0,nrow=n, ncol=freq)
for (i in 1:freq)
if (start==1) {dv[,i][seq(i,n,freq)]=1}
else if (i < start) {dv[,i][seq(i+1-start+freq,n,freq)]=1}
else {dv[,i][seq(i+1-start,n,freq)]=1}
return(dv)
}
# NB=per medie mobili centrate l'ordine deve essere dispari
wma=function(y, order=5, wts=c(1/8,1/4,1/4,1/4,1/8), centre=TRUE, plot=TRUE)
{
if (centre==TRUE)
{
n=length(y)
sy=rep(NA,n)
ord=(order-1)/2
for (i in (ord+1):(n-ord)) sy[i]=sum(wts*y[(i-ord):(i+ord)])
if (plot==TRUE)
{
plot(y,type="l")
lines(sy, col="red")
}
return(ts(sy))
}
if (centre==FALSE)
{
n=length(y)
sy=rep(NA,n)
for (i in (ord):(n)) sy[i]=sum(wts*y[(i-ord+1):(i)])
if (plot==TRUE)
{
plot(y,type="l")
lines(sy, col="red")
}
return(ts(sy))
}
}
wma2=function(y, m1=2, m2=2, wts=c(1/8,1/4,1/4,1/4,1/8), last=FALSE, plot=TRUE)
{
if (length(wts)!=m1+m2+1) print("Dimensione dei pesi errata")
if (last==FALSE)
{
n=length(y)
sy=rep(NA,n)
for (i in (m1+1):(n-m2)) sy[i]=sum(wts*y[(i-m1):(i+m2)])
if (plot==TRUE)
{
plot(y,type="l")
lines(sy, col="red")
}
return(ts(sy))
}
if (last==TRUE)
{
n=length(y)
sy=rep(NA,n)
ord=m1+1+m2
for (i in (ord):(n)) sy[i]=sum(wts*y[(i-ord+1):(i)])
if (plot==TRUE)
{
plot(y,type="l")
lines(sy, col="red")
}
return(ts(sy))
}
}
prevedi.arima=function(mod, passi, var.orig, i.ord=0)
{
if(i.ord==0)
{
pp=predict(mod, n.ahead=passi)
pre=new.env()
pre$pred=pp$pred
pre$sup=(pp$pred+1.96*pp$se)
pre$inf=(pp$pred-1.96*pp$se)
prev=as.list(pre)
return(prev)
}
if(i.ord==1)
{
nn=length(var.orig)
k=sum(mod$arma[1:4])+1 # somma degli ordini ar ed ma +1;
# individua la posizione della costante
a=mod$coef[k]
pp=predict(mod, n.ahead=passi)
pre=new.env()
pre$pred=var.orig[nn]+pp$pred+a*seq(1,passi,1)
pre$sup=var.orig[nn]+(pp$pred+1.96*pp$se)+a*seq(1,passi,1)
pre$inf=var.orig[nn]+(pp$pred-1.96*pp$se)+a*seq(1,passi,1)
prev=as.list(pre)
return(prev)
}
}
CS.matrice=function(CS, n.periodi=19, periodo=12, na.inizio=0, na.fine=4)
{
if ((na.inizio==0) & (na.fine==0))
CS.mat=matrix(CS,nrow=n.periodi,ncol=periodo,byrow=T)
if ((na.inizio==0) & (na.fine!=0))
CS.mat=matrix(c(CS,rep(NA,na.fine)),nrow=n.periodi,ncol=periodo,byrow=T)
if ((na.inizio!=0) & (na.fine==0))
CS.mat=matrix(c(rep(NA,na.fine), CS),nrow=n.periodi,ncol=periodo,byrow=T)
if ((na.inizio!=0) & (na.fine!=0))
CS.mat=matrix(c(rep(NA,na.fine), CS, rep(NA,na.fine)),nrow=n.periodi,ncol=periodo,byrow=T)
return(CS.mat)
}