2

I use the margins library in R to calculate AME's from a linear model. Normally I would use the stargazer library to create table which I can use in an academic paper. This is sadly, only possible for regression objects. Is there a efficant way to produce a similar table for the results returned from margins e.g. a library?

Thank you for your help!

Here is an example:

library(stargazer)
library(margins)

x <- lm(mpg ~ cyl * hp + wt, data = mtcars)
stargazer(x, out = 'foo.html', type = 'html') # This produces the desired outcome for the linear model

m <- margins(x)
summary(m) # I like to create a similar table as above for these results

Christoph
  • 45
  • 7
  • Why are you making an _HTML_ table for an academic _paper_ ? – jay.sf Jun 25 '20 at 05:19
  • @jay.sf I know it sounds crazy, and it is, but if we have co-authors who insist on using say Word, sometimes it's easier to import an HTML table into the Word document. – Jeremy K. Jun 25 '20 at 11:28
  • 1
    @jay.sf it's as Jeremy K. says. Not all my co-authers are familiar with using latex. So we use Word. And yes I regret it. ;) – Christoph Jun 26 '20 at 15:14

2 Answers2

1

A rather hackish idea using texreg. Use the base model x and, using the override .* options of the texreg::*reg functions, put in the AMEs. When you first create tables for the base models without overiding anything, the AME tables will look similar.

The AMEs should be extended by a preceding NA for the intercept and a following for the interaction (just to get the AMEs congruent to the coefficients). To ged rid of the GOFs use readLines identify the corresponding lines and omit them. cat saves the code into a file in your working directory.

sm <- rbind(NA, summary(m), NA)

library(texreg)

ame <- list(l=x, custom.model.names="AME", override.coef=sm[, 2], digits=3,
            override.se=sm[, 3], override.pvalues=sm[, 5], omit.coef="\\(|:", 
            caption="Average marginal effects")

## html version
ame.html <- do.call("htmlreg", ame)
tmp <- tempfile()
cat(ame.html, sep="\n", file=tmp)
ame.html <- readLines(tmp)
ame.html <- ame.html[-(el(grep("R<sup>2", ame.html)):grep("<tfoot>", ame.html))]
cat(ame.html, sep="\n", file="ame.html")


## latex version
ame.latex <- do.call("texreg", ame)
tmp <- tempfile()
cat(ame.latex, sep="\n", file=tmp)
ame.latex <- readLines(tmp)
ame.latex <- ame.latex[-(el(grep("R\\$\\^2\\$", ame.latex)):grep("multicolumn", ame.latex))]
cat(ame.latex, sep="\n", file="ame.tex")


## console version
ame.screen <- do.call("screenreg", ame)
tmp <- tempfile()
cat(ame.screen, sep="\n", file=tmp)
ame.screen <- readLines(tmp)
ame.screen <- ame.screen[-(grep("---", ame.screen)[2]:(grep("\\=", ame.screen)[2] - 1))]
cat(ame.screen, sep="\n")

Note: I tried to make the greps general, but you may need to adjust them according to your model.

Result

(showing console)

=====================
           AME       
---------------------
cyl         0.038    
           (0.600)   
hp         -0.046 ** 
           (0.015)   
wt         -3.120 ***
           (0.661)   
=====================
*** p < 0.001; ** p < 0.01; * p < 0.05
jay.sf
  • 60,139
  • 8
  • 53
  • 110
0

Yes, stargazer can output your results, if you first save them, then pass them to stargazer.

By default, if we pass a normal dataframe, stargazer will produce a summary table; which is not what we want. So we set summary = FALSE.

df<- summary(m) # I like to create a similar table as above for these results
stargazer(df, type = "text", summary = FALSE)

You can set the above to out = 'foo.html', type = 'html' for your output. The above returns:

==================================================
  factor  AME    SE     z       p    lower  upper 
--------------------------------------------------
1  cyl   0.038  0.600 0.064   0.949  -1.138 1.214 
2   hp   -0.046 0.015 -3.191  0.001  -0.075 -0.018
3   wt   -3.120 0.661 -4.718 0.00000 -4.416 -1.824
--------------------------------------------------
Jeremy K.
  • 1,710
  • 14
  • 35