R code for LaTeX tables of lmer model effects

Posted on Updated on


Here’s some R code that outputs text on the console that you can copy-paste into a .tex file and creates nice LaTeX tables of fixed effects of lmer models (only works for family=”binomial”). Effects <.05 will appear in bold. The following code produces the table pasted below. It assumes the model mod.all. prednames creates a mapping from predictor names in the model to predictor names you want to appear in the table. Note that for the TeX to work you need to include \usepackage{booktabs} in the preamble.

coefs = as.data.frame(summary(mod.all)@coefs)

coefs[,1] = round(coefs[,1],digits=2)
coefs[,2] = round(coefs[,2],digits=2)
coefs[,3] = round(coefs[,3],digits=1)
coefs[,4] = ifelse(coefs[,4] > .05, paste(round(coefs[,4],digits=1),sep=""), 
ifelse(coefs[,4] < .0001, "\\textbf{<.0001}", ifelse(coefs[,4] < .001,"\\textbf{<.001}",
ifelse(coefs[,4] < .01, "\\textbf{<.01}", "\\textbf{<.05}"))))

colnames(coefs) = c("Coef $\\beta$","SE($\\beta$)", "\\textbf{z}","\\textbf{p}")

prednames = data.frame(PName=row.names(coefs),NewNames=c("Intercept","I(some|pre)","I(some|head)","PMI",
"Collostructional strength", "I(some|GF)","I(head|some)","head frequency", "MassCount","length of pre","length of head"))

row.names(coefs) = prednames$NewNames[prednames$PName == row.names(coefs)]

latex(coefs,file="",title="",table.env=FALSE,booktabs=TRUE)
sample table

11 thoughts on “R code for LaTeX tables of lmer model effects

    Gregor Gorjanc said:
    June 29, 2010 at 5:36 pm

    Where do you get p-values in the lmer output?

    Like

    jdegen responded:
    June 30, 2010 at 8:57 am

    The above code operates on the output of an lmer call with family=”binomial” (that is, a logistic regression). For this case, summary(model)@coefs returns a matrix of p-values (along with coefficient estimates, standard errors, etc). If you’re doing linear regression, you can use the pvals.fnc() function to get p-values.

    For example, the following lets you access coefficient estimates, p-values etc of a model m:
    pvals.fnc(m,withMCMC=FALSE,addPlot=FALSE)$fixed

    To get only the p-values (based on MCMC simulation):
    pvals.fnc(m,withMCMC=FALSE,addPlot=FALSE)$fixed[5]

    Like

    Javier said:
    July 27, 2010 at 5:26 am

    Hi, thank you for the code! can you get p-values for a “quasibinomial” family lmer call?

    Thank you!

    Like

    Paul said:
    August 24, 2010 at 4:47 am

    Hi!

    Thank you! I added some code, amongst others to make it work for LMMs. See here: http://amor.rz.hu-berlin.de/~metznerp/tables.html

    Best,
    Paul

    Like

      tiflo said:
      August 25, 2010 at 3:35 am

      Hey Paul, thanks – that’s great!

      Like

    tiflo said:
    October 6, 2010 at 1:17 am

    Here is a wrapper around this function that saves the whole thing into a tex file which can be imported into your main tex file (0.05 steps towards Sweave ;). This saves another step. I also adjusted it a bit. The second function is an example of how one might use this in a specific project.

    createModelTable = function(m,
    dir=NA,
    filename= NA,
    predictor.names=NA,
    caption=””,
    digits.coef=2,
    digits.coefse=digits.coef,
    digits.statistic=1
    ) {
    coefs <- as.data.frame(summary(m)@coefs)

    coefs[,1] <- round(coefs[,1],digits=digits.coef)
    coefs[,2] <- round(coefs[,2],digits=digits.coefse)
    coefs[,3] <- round(coefs[,3],digits=digits.statistic)
    coefs[,4] .05,
    paste(“>”,round(coefs[,4],digits=1),sep=””),
    ifelse(coefs[,4] < .0001,
    "\\textbf{<.0001}",
    ifelse(coefs[,4] < .001,
    "\\textbf{<.001}",
    ifelse(coefs[,4] < .01,
    "\\textbf{<.01}",
    "\\textbf{<.05}"
    )))
    )

    colnames(coefs) <- c("Coef $\\beta$","SE($\\beta$)", "\\textbf{z}","\\textbf{p}")

    if (is.na(filename)) filename= paste(row.names(coefs), collapse="_")
    filename= paste(dir, "table-", filename, ".tex", sep="")
    if (!is.na(predictor.names)) row.names(coefs) = predictor.names

    sink(file=filename)
    latex(coefs,file=filename,title="",
    table.env=FALSE,
    booktabs=TRUE,
    caption=caption)
    sink()
    }

    createRelTable = function(m,
    name,

    ) {
    createModelTable(m, dir="../tables/", filename=name, …)
    }

    l.social= lmer(REL ~
    SpeakerEducation +
    cSpeakerMale +
    cSpeakerAge +
    (1|Speaker_ID),
    data=d.small, family="binomial"
    )
    createRelTable(l.social, caption= "Partial effects of social variables", name="socialmodel")

    then you can import the tex file anywhere into your main document with \import{.}{filename}, provided you have included \usepackage{import} and \usepackage{booktabs}.

    Like

    Boris Shor said:
    November 3, 2010 at 2:55 pm

    Any ideas on outputting random effects?

    Like

      jdegen responded:
      November 4, 2010 at 9:55 pm

      you can use this code to generate latex output for each random effect in your model. the code assumes the name of your model is “mod”:

      for (i in 1:length(ranef(mod)))
      {
      r <- ranef(mod)[[i]]
      print(latex(r,file="",title="",table.env=FALSE,booktabs=TRUE))
      }

      of course, you can also integrate this code into the wrapper that florian provided above.

      Like

    tiflo said:
    February 24, 2011 at 2:52 pm

    I debugged and extended the function a bit. So here’s an update to the above createModelTable()

    createModelTable = function(m,
    dir=NA,
    filename= NA,
    filenameInfix=””,
    predictor.names=NULL,
    caption=””,
    label=NA,
    digits.coef=2,
    digits.coefse=digits.coef,
    digits.statistic=1,

    ) {
    require(Design)
    coefs <- as.data.frame(summary(m)@coefs)

    coefs$Stars .1,
    “”,
    ifelse(coefs[,4] < .0001,
    "\\textbf{****}",
    ifelse(coefs[,4] < 0.001,
    "\\textbf{***}",
    ifelse(coefs[,4] < 0.01,
    "\\textbf{**}",
    ifelse(coefs[,4] < 0.05,
    "\\textbf{*}",
    "\\textbf{$^{+}$}"
    )))))
    coefs[,1] <- round(coefs[,1],digits=digits.coef)
    coefs[,2] <- round(coefs[,2],digits=digits.coefse)
    coefs[,3] <- round(coefs[,3],digits=digits.statistic)
    coefs[,4] 0.9″,
    ifelse(coefs[,4] > 0.1,
    paste(“>”,round(coefs[,4],digits=1),sep=””),
    ifelse(coefs[,4] < .0001,
    "<0.0001",
    ifelse(coefs[,4] < 0.001,
    "<0.001",
    ifelse(coefs[,4] < 0.01,
    "<0.01",
    ifelse(coefs[,4] < 0.05,
    "<0.05",
    "<0.1"
    ))))))
    )
    colnames(coefs) <- c("Coef $\\beta$","SE($\\beta$)", "\\textbf{z}","\\textbf{p}","\ ")

    if (is.na(label)) label= paste("table:", filename, sep="")
    if (is.na(filename)) filename= paste(row.names(coefs), collapse="_")
    filename= paste(dir, "table-", filename, filenameInfix, ".tex", sep="")
    if (!is.null(predictor.names)) row.names(coefs) = predictor.names

    sink(file=filename)
    latex(coefs,file=filename,
    title="",
    table.env=FALSE,
    booktabs=TRUE,
    caption=caption,
    label=label, …
    )
    sink()
    }

    Like

    carlosgomezgallo said:
    February 28, 2011 at 6:32 am

    Hi,
    I think there are couple of typos:

    coefs$Stars .1,
    “”,
    ifelse(coefs[,4] < .0001,

    should be:

    coefs$Stars =
    ifelse(coefs[,4] 0.1,

    should be:

    coefs[,4] =
    ifelse(coefs[,4] > 0.1,

    Also, I am not sure what the purpose is for the dots (…), but my R shell did not allow them in the code:

    label=label, …

    digits.statistic=1,

    ) {

    Thanks,
    C

    Like

      tiflo said:
      February 28, 2011 at 11:32 am

      The “…” hands left over arguments from the top function to its embedded function(s).

      As for the rest, something must have gone wrong in copying things (HTML conversion). Let me see. Ah, I had used LEFT-ASSIGN ARROW instead of =.

      Here is the revised code:
      createModelTable = function(m,
      dir=NA,
      filename= NA,
      filenameInfix=””,
      predictor.names=NULL,
      caption=””,
      label=NA,
      digits.coef=2,
      digits.coefse=digits.coef,
      digits.statistic=1,

      ) {
      require(Design)
      coefs = as.data.frame(summary(m)@coefs)

      coefs$Stars = ifelse(coefs[,4] > .1,
      “”,
      ifelse(coefs[,4] < .0001,
      "\\textbf{****}",
      ifelse(coefs[,4] < 0.001,
      "\\textbf{***}",
      ifelse(coefs[,4] < 0.01,
      "\\textbf{**}",
      ifelse(coefs[,4] < 0.05,
      "\\textbf{*}",
      "\\textbf{$^{+}$}"
      )))))
      coefs[,1] <- round(coefs[,1],digits=digits.coef)
      coefs[,2] <- round(coefs[,2],digits=digits.coefse)
      coefs[,3] <- round(coefs[,3],digits=digits.statistic)
      coefs[,4] 0.9″,
      ifelse(coefs[,4] > 0.1,
      paste(“>”,round(coefs[,4],digits=1),sep=””),
      ifelse(coefs[,4] < .0001,
      "<0.0001",
      ifelse(coefs[,4] < 0.001,
      "<0.001",
      ifelse(coefs[,4] < 0.01,
      "<0.01",
      ifelse(coefs[,4] < 0.05,
      "<0.05",
      "<0.1"
      ))))))
      )
      colnames(coefs) = c("Coef $\\beta$","SE($\\beta$)", "\\textbf{z}","\\textbf{p}","\ ")

      if (is.na(label)) label= paste("table:", filename, sep="")
      if (is.na(filename)) filename= paste(row.names(coefs), collapse="_")
      filename= paste(dir, "table-", filename, filenameInfix, ".tex", sep="")
      if (!is.null(predictor.names)) row.names(coefs) = predictor.names

      sink(file=filename)
      latex(coefs,file=filename,
      title="",
      table.env=FALSE,
      booktabs=TRUE,
      caption=caption,
      label=label, …
      )
      sink()
      }

      Like

Questions? Thoughts?