Kay Kay - 22 days ago 10
R Question

How to loop all values in a dataframe as the start value in maxLik

I'm doing Maximum Likelihood Estimation using

maxLik
, which requires specifying starting values. Instead of specifying a single value, is there any way that allows me to use all the values from a matrix as the start value?

My current code of
maxLik
is:

f12 <- function(param){
alpha <- param[1]
rho <- param[2]
lambda <- param[3]
u <- 0.5*(p12$v_50_1)^alpha + 0.5*lambda*(p12$v_50_2)^alpha
p <- 1/(1 + exp(-rho*u))
f <- sum(p12$gamble*log(p) + (1-p12$gamble)*log(1-p))}

ml <- maxLik(f12, start = c(alpha = 1, rho=2, lambda = 1), method = "NM")


I create a dataframe with the upper and lower bounds of potential start values:

st <- expand.grid(alpha = seq(0, 2, len = 100),rho = seq(0, 1, len = 100),lambda = seq(0,2, length(100))


There are 3 parameters in my function, and my goal is to loop all the values in the above dataframe
st
and select the best vector of start values after running the model from a variety of starting parameters.

Thanks!

Answer Source

Consider Map (wrapper to mapply) to pass the st columns elementwise through your methods. Here, Map will return a list of maxLik objects, specifically inherited maxim class objects containing a list of other components. The number of items in this list will be equal to rows of st.

Notice input parameters, a, r, and l being passed into start argument of maxLik() and no longer hard-coded integers. And f12 is left untouched.

maxLik_run <- function(a, r, l) {
   tryCatch({
      f12 <- function(param){
        alpha <- param[1]
        rho <- param[2]
        lambda <- param[3]
        u <- 0.5*(p12$v_50_1)^alpha + 0.5*lambda*(p12$v_50_2)^alpha
        p <- 1/(1 + exp(-rho*u))
        f <- sum(p12$gamble*log(p) + (1-p12$gamble)*log(1-p))
      }

      return(maxLik(f12, start = c(alpha = a, rho = r, lambda = l), method = "NM"))
   }, error = function(e) return(NA))  
}

st <- expand.grid(alpha = seq(0, 2, len = 100),
                  rho = seq(0, 1, len = 100),
                  lambda = seq(0, 2, length(100)))

maxLik_list <- Map(maxLik_run, st$alpha, st$rho, st$lambda)

And to answer the question --best vector of start values after running the model from a variety of starting parameters-- requires a particular definition of "best". Once you define this, you can use Filter() on your returned list of objects to select the one or more element that yields this "best".

Below is a demonstration to find the highest value across each maximum likelihood's maximum. Use estimate if needed. Do note, this returned list can have more than one if the highest value is shared by other list items:

highest_value <- max(sapply(maxLik_list, function(item) item$maximum))

maxLik_item_list <- Filter(function(i) i$maximum == highest_value, maxLik_list)