Search code examples
rnnetemmeans

Error thrown with nnet::multinom() passing programmed as.formula() to emmeans::emmeans()?


One can get the data referenced below from: https://gist.github.com/markhwhiteii/6ce74461a789ddc6d04044de73d99939

I can pass an interaction for a multinomial logistic model to get post hoc tests by hard-coding things:

library(nnet)
library(emmeans)
model <- multinom(outcome ~ cond * party, data)
emmeans(model, ~ outcome + cond | party)

However, I need to have a wrapper function for this. If I have inputs that are the variables, then pass these as.formula(), then I get an error thrown at me:

iv <- "cond"
dv <- "outcome"
mod <- "party"
formula <- as.formula(paste(dv, "~", iv, "*", mod))
model <- multinom(formula, data)
emmeans(model, as.formula(paste("~", dv, "+", iv, "|", mod)))

The call to emmeans generates:

Error in object$call$formula[[2]] : 
  object of type 'symbol' is not subsettable

It seems like it is coming from the multinom function, as I can get the pasted formula in emmeans to run with the hard-coded multinom model. It is strange, because I have gotten this method to work with lm, glm, and clm models. I looked at the structure of the two model objects, and they seem to be identical. Importantly, model$terms for both is identical. emmeans calls a function which calls a function which calls a method, etc., so it is difficult to figure out where the error is happening using the debugger.


Solution

  • I figured out a hack to get around this. multinom was storing the object name formula, not the formula itself, into the call attribute of the model:

    iv <- "cond"
    dv <- "outcome"
    mod <- "party"
    formula <- as.formula(paste(dv, "~", iv, "*", mod))
    model <- multinom(formula, data)
    model$call$formula
    

    Which returns the character formula.

    I can then re-create the error with:

    > model$call$formula[[2]]
    Error in model$call$formula[[2]] : 
      object of type 'symbol' is not subsettable
    

    So, I just manually wrote-over what multinom stored:

    iv <- "cond"
    dv <- "outcome"
    mod <- "party"
    formula <- as.formula(paste(dv, "~", iv, "*", mod))
    model <- multinom(formula, data)
    model$call$formula <- formula
    emmeans(model, as.formula(paste("~", dv, "+", iv, "|", mod)))
    

    And it works.