Barnaby
Barnaby

Reputation: 1480

Error Lag function

I have the following vector which is autocorrelated and functions (package quantmod)

### rm(list=ls())
s <- filter(rnorm(100), filter=rep(1,3), circular=TRUE)
a <- acf(s)
b <- a[[1]] 
c <- (b[2:length(b)])
posssignificance_level <- qnorm((1+0.90)/2)/sqrt(sum(!is.na(s)))
negsignificance_level <- -posssignificance_level
poscorr <- which(posssignificance_level<c)
negcorr <- which(negsignificance_level>c)

Using negcorr and poscorr different coefficients in each I would like to produce a number of columns with the lag/s I obtained by poscorr and negcorr. I do

posautorrelation  <- Lag(s, poscorr)
negautorrelation  <- Lag(s, negcorr)

However I obtain the following error mesagge for both

Error en `tsp<-`(`*tmp*`, value = p - (k/p[3L]) * c(1, 1, 0)) : 
el atributo 'tsp' debe ser numérico de longitud tres
Además: Mensajes de aviso perdidos
1: In if (k != round(k)) { :
la condición tiene longitud > 1 y sólo el primer elemento será usado
2: In (k/p[3L]) * c(1, 1, 0) :
longitud de objeto mayor no es múltiplo de la longitud de uno menor
3: In p - (k/p[3L]) * c(1, 1, 0) :
longitud de objeto mayor no es múltiplo de la longitud de uno menor
Error durante el wrapup: no se puede abrir la conexión

Would you happen to know why is the error ocurring and what expression would I have to use as to produce the columns for posautorrelation and negautorelation

Upvotes: 0

Views: 2120

Answers (1)

Gavin Simpson
Gavin Simpson

Reputation: 174853

tl;dr

There is no Lag() method for class "ts", hence it dispatches to the base function lag() which doesn't like the vector of k lags being passed here. A solution is to force the use of the Lag.numeric() method or coerce the time series s to one of the supported classes; "numeric" or "zoo" for example.

Detail

The problem is that the default method for Lag() dispatches to lag() and from what I can tell, it expects only to have a single lag k provided. If you follow this down, you will see a line in stats:::lag.default which computes

tsp(x) <- p - (k/p[3L]) * c(1, 1, 0)

where p is the tsp() of the input data, k is the lag. When you pass in a vector of K > 1 lags k, you get this:

R> p - (poscorr/p[3L]) * c(1, 1, 0)
[1]  0 98  1
Warning message:
In (poscorr/p[3L]) * c(1, 1, 0) :
  longer object length is not a multiple of shorter object length

(for example using some of your data).

Next note that 'tsp<-'() sets the "tsp" attribute of its argument vector x via

attr(x, "tsp") <- value

and if you debug down far enough you'll find this is the line raising the Error. If we read ?attr we see that the "tsp" attributes are handled as a special case

 Note that some attributes (namely ‘class’, ‘comment’, ‘dim’,
 ‘dimnames’, ‘names’, ‘row.names’ and ‘tsp’) are treated specially
 and have restrictions on the values which can be set.  (Note that
 this is not true of ‘levels’ which should be set for factors via
 the ‘levels’ replacement function.)

and it is from the C code that we must go looking for why the error is raised. If we skip that bit, we can just infer that

R> p - (poscorr/p[3L]) * c(1, 1, 0)
[1]  0 98  1

are not valid for the time series s supplied to Lag() originally.

A work around is simply to call a more appropriate Lag() method directly. There is a "numeric" method, but for that to work you need to convert s to a numeric vector, al call the "numeric" method directly:

quantmod:::Lag.numeric(s, poscorr)

R> head(quantmod:::Lag.numeric(s, poscorr))
       Lag.1   Lag.2
[1,]      NA      NA
[2,] -1.5363      NA
[3,] -0.2461 -1.5363
[4,] -0.3276 -0.2461
[5,] -0.8280 -0.3276
[6,] -0.2980 -0.8280

or by coercion

Lag(as.numeric(s), poscorr)

R> head(Lag(as.numeric(s), poscorr))
       Lag.1   Lag.2
[1,]      NA      NA
[2,] -1.5363      NA
[3,] -0.2461 -1.5363
[4,] -0.3276 -0.2461
[5,] -0.8280 -0.3276
[6,] -0.2980 -0.8280

The latter being the preferred way here. You can also coerce to a "zoo" class object:

Lag(as.zoo(s), poscorr)

R> head(Lag(as.zoo(s), poscorr))
    Lag.1   Lag.2
1      NA      NA
2 -1.5363      NA
3 -0.2461 -1.5363
4 -0.3276 -0.2461
5 -0.8280 -0.3276
6 -0.2980 -0.8280

Lag() should probably catch this and bail out if vector k is going to be passed to lag(). Or it could sapply() over the k for multiple lag() calls, as it does in the "numeric" case.

Upvotes: 2

Related Questions