1

I have a multinomial logistic regression model built using multinom() function from nnet package in R. I have a 7 class target variable and I want to plot the coefficients that the variables included in the model have for each class of my dependent variable.

For a binary logistic regression I used coefplot() function from arm package, but I don't know how to do this for a multiclass problem.

I want my plots to look like this: Example of plot

Alan
  • 129
  • 1
  • 13

2 Answers2

4

I couldn't easily find a sensible multinom() example: the one below gives ridiculous values, but the structure of the code should work anyway. The basic idea is to use broom::tidy() to extract coefficients and ggplot/ggstance to plot them. ggstance is specifically for plotting horizontal point-ranges and displacing them from each other an appropriate amount; this can also be done via coord_flip(), but coord_flip() induces a certain lack of flexibility (e.g. it can't easily be combined with faceting).

library(nnet)
library(broom)
library(ggplot2); theme_set(theme_bw())
library(ggstance)

Create example multinom() fit:

nvars <- c("mpg","disp","hp")
mtcars_sc <- mtcars
mtcars[nvars] <- scale(mtcars[nvars])
m <- multinom(cyl~mpg+hp+disp,mtcars_sc,
              maxit=1e4)

Extract coefficients and drop intercept terms:

tt <- broom::tidy(m,conf.int=TRUE)
tt <- dplyr::filter(tt, term!="(Intercept)")

Plot:

ggplot(tt, aes(x=estimate,y=term,colour=y.level))+
  geom_pointrangeh(aes(xmin=conf.low,
                     xmax=conf.high),
    position=position_dodgev(height=0.75))
Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
1

Given that you're able to get your data like this:

coeff <- factor(1:7,labels=c("inc", "lwg", "hcyes", "wcyes","age", "k618", "k5"))
values <- c(-0.1,0.6,0.15,0.8,-0.05,-0.05,-1.5)
upper <- c(-0.1,1,.6,1.3,-.05,.1,-1)
lower <- c(-0.1,.2,-.2,.3,-.05,-.2,-2)

df <- data.frame(coeff,values,upper,lower)

Then all you have to do is run:

library(ggplot2)

ggplot(df, aes(x=coeff, y=values, ymin=lower, ymax=upper)) + 
  geom_pointrange() + 
  geom_hline(yintercept=0, linetype=2)+
  coord_flip() 

The result should look like this:

You can experiment with certain options to get it to look identical to your example

Jarn Schöber
  • 309
  • 1
  • 8
  • coord_flip( reverses the order, look [here](https://stackoverflow.com/questions/34227967/reversed-order-after-coord-flip-in-r) for a fix – Jarn Schöber Aug 13 '19 at 13:31