3

When using an R package called did, I get this error:

Error in solve.default(preV) :    system is computationally singular:
reciprocal condition number = 4.09946e-19

The solve function has an argument called tol whereby I can set the tolerance and thereby avoid the problem. But the package does not give this option to specify this tol from its top-level functions, so there is no way to set tol for solve.

I am thinking about an alternative. Since solve() defaults using .Machine$double.eps for tol, it would be good if I could decrease this default value. How?

Zheyuan Li
  • 71,365
  • 17
  • 180
  • 248

1 Answers1

4

That is something you can't decrease as it is sort of a C-standard. However, you can manually set tol = 1e-20 as a function input for example, to override the default tolerance. But, this is purely a numerical workaround. You need to think about whether it is possible to address your rank-deficiency issue at your problem level. For example, rank-deficiency can arise due to the poor scaling between your data variables, and here is a simple example: Linear model singular because of large integer datetime in R?.


I not sure as to what to do here then? As I said I'm using a function called mp.spatt where the solve function is used. So I can't really (or at least I don't know how?) add the tol = blabla argument in the solve function?

You could write a patched version of that function and rebuild the package for your own use. This is exactly why open-source software and packages are so GREAT.

Go to https://cran.r-project.org/package=did, download the source file .tar.gz for Linux, .tgz for Mac or .zip for Windows. Extract it, open the "did.R" file in the /R director / folder. Function solve is only used once in this file, so you can easily locate it:

W <- n*t(preatt)%*%solve(preV)%*%preatt

You can add tol = 0 for simplicity. Or, you many replace solve by MASS::ginv. Actually, the package authors have been using MASS::ginv everywhere else in the script. It could be the case that he just forgot to replace this solve as well (I am checking the latest version 1.1.0 on 2018/07/11).

After fixing it, generate a .tar.gz, .tgz or .zip file again. Open your R, use install.packages to install this specific file, and happily use it.

Zheyuan Li
  • 71,365
  • 17
  • 180
  • 248
  • 3
    But you cannot increase `tol` beyond the machine precision as that would be metaphysics so with `1e-20` you _are_ fooling yourself. – Dirk Eddelbuettel Jul 18 '18 at 15:14
  • @DirkEddelbuettel what would you do in my case? how do i interpret these results? is simply because i'm trying to do something that isn't correct math? – William Parker Jul 18 '18 at 15:27
  • From `help(".Machine")`, list member `double.eps`: *the smallest positive floating-point number x such that 1 + x != 1.* So no, you cannot improve on it. – Rui Barradas Jul 18 '18 at 15:30
  • when i download the did.zip from cran as suggested and open the did.r i only get the following: #Some comments that i cant write do to character limit. local({ info <- loadingNamespaceInfo() pkg <- info$pkgname ns <- .getNamespace(as.name(pkg)) if (is.null(ns)) stop("cannot find namespace environment for ", pkg, domain = NA); dbbase <- file.path(info$libname, pkg, "R", pkg) lazyLoad(dbbase, ns, filter = function(n) n != ".__NAMESPACE__.") }) – William Parker Jul 30 '18 at 15:07
  • @ParkerWilliam Ah, I see. Windows and Mac only have pre-compiled binary rather than source code. So Open-Source is only Open on Linux. There should be a way to work around on Windows, maybe with `Rtools`. But I am not a Windows user so I don't know. – Zheyuan Li Jul 30 '18 at 20:25
  • @李哲源 thanks for the help anyway, just to be sure would you agree that the error is likely to be do to a to small dataset? that the numbers become so small that R and my computer just treats them as being 0. – William Parker Jul 31 '18 at 11:52