Patty
Patty

Reputation: 167

Unsure what's causing this error in R (pmvt - Package: mvtnorm)?

I have a simple hazard function, the line causing the error is marked.

h <- function(t,u) {
    x <- 1 - Sa(t)
    y <- 1 - Sm(u)
    invx <- as.numeric(qt(x,df=d1))
    invy <- as.numeric(qt(x,df=d1))
    [ERROR LINE] copula <-  pmvt(lower=as.numeric(cbind(-9999,-9999)),upper=cbind(invx,invy),df=d1,corr=matrix(cbind(1,d2,d2,1),byrow=T,ncol=2)  )
    density <- dmvt(cbind(invx,invy),sigma=matrix(cbind(1,d2,d2,1),byrow=T,ncol=2),df=d1)
    num <- (sa(t)*sm(u))*density/dt(invx,df=d1)/dt(invy,df=d1)
    den <- 1 - x - y + copula
    hazard <- num/den
    return(hazard)
}

This hazard function is then called on by a likelihood function:

# log Likelihood function for each individual car i
lli <- function(data) {
  result <- 0;
  # for all claims, evaluate hazard function at that point
  if (nrow(data)> 2) {
    for (k in 1:nrow(data)) {
      if (data[k,3] == 1) {
    result <- result + log(h(data[k,2],data[k,1]));
      }
     }
  }
  # integrate hazard function over areas between claims
  for (k in 1:(nrow(data)-1)) {
    integral <- quad2d(h,data[k,2],data[k+1,2],data[k,1],data[k+1,1]);
    result <- result - integral;
  }
  return(result)
}

Now this likelihood function is then called on by a third function to use over my entire data set; however it is the above function that is causing the error, not the function below

# log Likelihood function over all vehicles
ll <- function(x) {
# Unpack parameters
  d1 <<- x[1];
  d2 <<- x[2];
  total <- 0;
  # Get log Likelihood for each vehicle
  for (i in 1:length(alldata)) {
    total <- total + lli(alldata[[i]]);
    #print(sprintf("Found candidate solution %d value: %f",i,total));
  }
  #print(sprintf("Found candidate solution value: %f",total));
  if (is.nan(total)) { #If it is undefined, make it a large negative number
    total <- -2147483647 ;
  }
  return(-1*total); # Minimise instead of maximise
}

Error message is as follows:

> ll(cbind(50,0.923))
Error in checkmvArgs(lower = lower, upper = upper, mean = delta, corr = corr,  : 
  ‘diag(corr)’ and ‘lower’ are of different length

I kept getting this same error when using pmvnorm, and ended up having to use the pbivnorm package to get around this. I can't find an alternative package for the bivariate t distribution though. I don't understand what the problem is. When I call the function h(t,u) by itself it executes without a problem. But when lli(data) calls h(t,u), it doesn't work. What's even more bizarre is that they are the same length.

> length(as.numeric(cbind(-9999,-9999)))
[1] 2
> length(diag(matrix(cbind(1,d2,d2,1),byrow=T,ncol=2)))
[1] 2

I apologize for the messy code. I don't use R much. Anyway this has me completely stumped.

Data file is here: https://files.fm/u/yx9pw2b3


Additional code I forgot to include, basically some constants and marginal CDF functions:

Marginals.R:

p1 <- 0.4994485;
p2 <-  0.2344439;
p3 <- 0.1151654;
p4 <- 0.1509421;

b1 <- 0.7044292
t1 <- 1713.3170267
mu1 <- 7.014415
sig1 <- 1.394735
mu2 <- 6.926146
sig2 <- 1.056647
mu3 <- 6.7995896
sig3 <- 0.7212853
b2 <- 0.6444582
t2 <- 762.9962093
b3 <- 1.494303
t3 <- 410.828780

b1 <- 0.903
t1 <- 864.896
b2 <- 0.9109 
t2 <- 314.2946
# Marginal survival distribution and density
Sa <- function(t) {return(exp(-(t / t1) ** b1))}
Sm <- function(u) {return(exp(-(u / t2) ** b2))} 
sa <- function(t) {return((t / t1) ** b1 * b1 * exp(-(t / t1) ** b1) / t ) }
sm <- function(u) {return((u / t2) ** b2 * b2 * exp(-(u / t2) ** b2) / u ) }

Upvotes: 1

Views: 1125

Answers (1)

Sixiang.Hu
Sixiang.Hu

Reputation: 1019

Summary:
The problem is the difference length between lower and upper when calling pvmt, which upper has a length of 2048, while lower has length of 2.

Reasoning:
1. pmvt checks the coming parameters by calling checkmvArgs in mvtnorm package.
2. In checkmvArgs, lower, upper and mean have been put together by rec <- cbind(lower, upper, mean). Here the new data rec has 2048 row instead of 2.
3. lower is then replace by lower <- rec[, "lower"], which lower now has length 2048 instead of 2.
4. Given corr is still a 2 * 2 matrix, error occurs when checking length(corr) != length(lower)

Solution:

  invx <- as.numeric(qt(x,df=d1))  
  invy <- as.numeric(qt(x,df=d1))

upper mean to be a length 2 vector, hence invx and invy needs to be single numbers.

As not sure what's the upper range you want to define, I cannot solve it further. Possible one is :

  invx <- as.numeric(qt(x,df=d1))
  invy <- as.numeric(qt(x,df=d1))
  copula <-  pmvt(lower=as.numeric(cbind(-9999,-9999)),upper=range(c(invx,invy)),df=d1,corr=matrix(c(1,d2,d2,1),byrow=T,ncol=2)  )

Which is using the range of invx and invy as the input. Hence the dmvt would not be affect.

Note:
As value a is not provided, the next line below (calling dmvt) the error line failed.

Edit: To make the issue more specific: 1. quad2d will generate a Gauss-Legendre Quadrature which will be created by default a length of 32 on a given range. And,
2. Your function h is then called with the x and y from this Gauss-Legendre Quadrature. Hence, the t and u defined in h is not a single mumber, instead, it is a vector.

Upvotes: 2

Related Questions