1

I want to output a plot for the average marginal effect returned from the margins package. The variables are on the x axis but they are in the incorrect order and all variable names are not displayed. I would like to display all variable names in the correct order and rotate 90 degrees. This is my code:

margins_logit <- margins(LOGIT, variables=c("AGE", "AGE_SQRD", "LOGINCOME", "LOGINCOME_SQRD", "LOGSPEND", "LOGSPEND_SQRD"))

categories <- c(
                "AGE",
                "AGE_SQRD",
                "LOGINCOME",
                "LOGINCOME_SQRD",
                "LOGSPEND",
                "LOGSPEND_SQRD"
)

plot(margins_var, main="", xlab ="", xaxt='n', ann=TRUE)
axis(1, at=1:6, labels=categories, las = 2, cex.axis = 0.8)

I followed this: Remove plot axis values but it does not seem to work for me.

Many thanks!

Pontus

The vertical x categorical values are correct but the horizontal are in the wrong place and all categories are not displayed. I'd like to remove these completely and replace them with axis.

2 Answers2

0

the 'xaxt' will work for most plots, but for you have a margins object and you call margins:::plot.margins when you run this plot(margins_var..). Inside margins:::plot.margins they actually put the labels on using the axis command, hence you see your labels twice.

I don't have your data, so I use the mtcars example to show you 2 workarounds:

library(margins)
fit <- lm(mpg ~ cyl + qsec+vs+am+carb, data = mtcars)
# the order you want them
categories <- c("cyl","qsec","am","carb")
margins_lm <- margins(fit,variables=categories)

df <- summary(margins_lm)
df <- df[match(categories,df$factor),]
LIMITS <- range(c(df$AME+df$SE,df$AME-df$SE))
plot(NULL,xlim=c(1,nrow(df)),ylim=LIMITS,xaxt='n',
xlab="",ylab="Average Marginal Effect")
with(df,points(1:nrow(df),AME,pch=20))
with(df,segments(x0 = 1:nrow(df),y0=AME-SE,y1=AME+SE))
axis(1, at=1:length(categories), labels=categories, 
las = 2, cex.axis = 0.8)

enter image description here

Or simply use df from above, and apply ggplot2:

ggplot(df,aes(x=factor,y=AME)) + 
geom_point() + 
geom_segment(aes(y=lower,yend=upper,x=factor,xend=factor)) + 
theme_bw() + 
scale_x_discrete(limits=categories)

enter image description here

StupidWolf
  • 34,518
  • 14
  • 22
  • 47
0

I have no experience with this package. I have just tried to use the mtcars data to reproduce your problem as a learner.

Problem

x <- glm(am ~ cyl + hp + disp, data = mtcars, family = binomial)

margins_var <-margins(x, type = "response", 
                      variables = c("disp", "cyl", "hp"))
categories <- c(
  "disp label",
  "cyl label",  
  "hp label"
)

plot(margins_var, main="", xlab = "",  xaxt='n', ann=FALSE)

axis(1, at=1:3, labels=categories, las = 2, cex.axis = 0.8)
[![enter image description here][1]][1]

enter image description here

Fix

  1. I guess the order may be determined by the original model.
  2. To add vertical label, we need to remove the horizontal label first.
x <- glm(am ~ cyl + hp + disp, data = mtcars, family = binomial)

margins_var <-margins(x, type = "response", 
                      variables = c("cyl", "hp", "disp"))
categories <- c(
  "Cyl",
  "Hp",  
  "Disp"
)
plot(margins_var, main="", xlab = "", labels = c(" ", " ", " "))
axis(1, at=1:3, labels=categories, las = 2, cex.axis = 0.8)

enter image description here

Community
  • 1
  • 1
Zhiqiang Wang
  • 3,620
  • 2
  • 4
  • 18