[R] Newey West and Singular Matrix + library(sandwich)
Achim Zeileis
Achim.Zeileis at uibk.ac.at
Thu Sep 23 15:05:32 CEST 2010
On Thu, 23 Sep 2010, ivo welch wrote:
> thank you, achim. I will try chol2inv.
>
> sandwich is a very nice package, but let me make some short
> suggestions. I am not a good econometrician, so I do not know what
> prewhitening is,
In general it means, that you do not look at a (typically multivariate)
series Y, but at the residuals of a VAR(p) model for Y. In case of
HAC covariances, people do not use the empirical estimating functions
directly, but the residuals of a VAR(1) model.
> and the vignette did not explain it. "?coeftest" did
> not work after I loaded the library.
Presumably because you did load "sandwich" but did not load the "lmtest"
package in which coeftest() is provided.
> automatic bandwidth selection can be a good thing, but is not always.
As my short command in the previous mail showed, it can be conveniently
set to any other value, just by specifying the "lag" argument.
> as to my own little function, I like the idea of specifying my choice
> of overlapping periods. for me, the need often arises in a case of
> regressions in which the variables are measured over overlapping
> intervals, so I know the number of periods to worry about. besides,
> my function has an attractive simplicity to it. it is short.
>
> assert does indeed not exist in R, but it should be. YMMV.
But the code would be even shorter without it ;-) Just kidding...
hth,
Z
> assert <- function( cond, ... ) { if (!cond) cat(...,
> file=stderr()); stopifnot(cond) }
>
> thanks again.
>
> /iaw
>
> On Wed, Sep 22, 2010 at 7:41 PM, Achim Zeileis <Achim.Zeileis at uibk.ac.at> wrote:
>> On Wed, 22 Sep 2010, ivo welch wrote:
>>
>>> dear R experts: I am writing my own little newey-west standard error
>>> function, with heteroskedasticity and arbitrary x period
>>> autocorrelation corrections. including my function in this post here
>>> may help others searching for something similar. it is working quite
>>> well, except on occasion, it complains that
>>>
>>> Error in solve.default(crossprod(x.na.omitted, x.na.omitted)) :
>>> system is computationally singular: reciprocal condition number =
>>> 3.63797e-23
>>>
>>> I know that lm can do the inversion, so I presume that there is a more
>>> stable way than qr.solve . I looked into lm, then into lm.fit, and it
>>> seems to invoke dqrls . is this the recommended way, or is there a
>>> higher-level more stable matrix inversion routine that I could use?
>>
>> I typically leverage chol2inv(). In "strucchange" I've written a small
>> convenience function solveCrossprod() that provides two different approaches
>> (plus the naive method). The man page has a few comments. The function
>> defintions are all one-liners, though.
>>
>>> help is, as always, appreciated. (also, if you see something else
>>> silly in my code, let me know, please.)
>>
>> 1. There is no assert() function in base R.
>> 2. The error message of se.neweywest() refers to se.white.
>> 3. A much more flexible and powerful solution of this is included
>> in package "sandwich", see the vignette for details. The code
>> sqrt(diag(NeweyWest(lm_object, lag = 0, prewhite = 0)))
>> replicates se.neweywest(lm_object) but has the following advantages:
>> it also does automatic bandwidth selection, it does not require setting
>> "x = TRUE", it incorporates other kernel weighting functions, supports
>> prewhitening etc.
>>
>> Best,
>> Z
>>
>>> regards,
>>>
>>> /iaw
>>>
>>>
>>> se.neweywest <- function( lmobject.withxtrue, ar.terms =0 ) {
>>> assert( (class(lmobject.withxtrue)=="lm"),
>>> "[se.white] works only on 'lm' objects, not on ",
>>> class(lmobject.withxtrue), "objects \n" )
>>> x.na.omitted <- lmobject.withxtrue$x
>>> assert( class(x.na.omitted)=="matrix", "[se.white] internal
>>> error---have no X matrix. did you invoke with 'x=TRUE'?\n")
>>> r.na.omitted <- residuals( lmobject.withxtrue )
>>>
>>> diagband.matrix <- function( m, ar.terms ) {
>>> nomit <- m-ar.terms-1
>>> mm <- matrix( TRUE, nrow=m, ncol=m )
>>> mm[1:nomit,(ncol(mm)-nomit+1):ncol(mm)] <- (lower.tri(
>>> matrix(TRUE, nrow=nomit, ncol=nomit) ))
>>> mm[(ncol(mm)-nomit+1):ncol(mm),1:nomit] <- (upper.tri(
>>> matrix(TRUE, nrow=nomit, ncol=nomit) ))
>>> mm
>>> }
>>>
>>> ## V(b) = inv(X'X) X' diag(e^2) X inv(X'X)
>>> invx <- qr.solve( crossprod( x.na.omitted, x.na.omitted ) )
>>> if (!ar.terms) resid.matrix <- diag( r.na.omitted^2 ) else {
>>> full <- r.na.omitted %*% t(r.na.omitted)
>>>
>>> ## the following is not particularly good. see, we could zero out also
>>> ## items which are multiplications with a missing residual for example,
>>> ## if we do an ar1 correction, and obs 5 is missing, then the AR term on
>>> ## 4 and 6 could be set to 0. right now, we just adjust for an add'l
>>> ## term.
>>>
>>> maskmatrix <- diagband.matrix( length(r.na.omitted), ar.terms )
>>> resid.matrix <- full * maskmatrix
>>> }
>>>
>>> invx.x <- invx %*% t(x.na.omitted)
>>> vmat <- invx.x %*% resid.matrix %*% t(invx.x)
>>> sqrt(diag(vmat))
>>> }
>>>
>>> ______________________________________________
>>> R-help at r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-help
>>> PLEASE do read the posting guide
>>> http://www.R-project.org/posting-guide.html
>>> and provide commented, minimal, self-contained, reproducible code.
>>
>
More information about the R-help
mailing list