Search code examples
rquartomodelsummary

Assigning different coefficient names and goodness of fit statistics to different panels in modelsummary


I am trying to make a table using the modelsummary package in R (thank you to the creator) which has different goodness of fit statistics and names for different panels. I have been unable to achieve this so far. I am working in Quarto.

Here is an example (never mind the validity of the regression). I would like to have the adjusted R squared in the first panel, but not the second. I would also like the coefficients to be renamed as in the coefficient mapping, but this does not seem to be happening.

Very grateful for your help.

library(modelsummary)
gm<-tibble::tribble(~raw,~clean,~fmt,
                    "nobs","N",0,
                    "adj.r.squared","Adj. $R^2$",2)

cm <- c("qsec" = "OLS",
        "fit_qsec" = "TSLS")


panels <- list(
  "OLS" = list(
    "(I)" = feols(mpg ~ 1 + qsec, data = mtcars),
    "(II)" = feols(hp ~ 1 + qsec, data = mtcars)
  ),
  "TSLS" = list(
    "(I)" = feols(mpg ~ 1| qsec~drat,data = mtcars),
    "(II)" = feols(hp ~ 1| qsec~drat,data = mtcars)
  )
)

modelsummary(
  panels,
  shape = "rbind",
  cof_map = cm,
  gof_map = gm)



Solution

  • Thanks for the question.

    First, there’s a typo in your example: cof_map.

    Second, there’s not a built-in way to use different arguments like gof_map in different panels. However, maybe you can hack your way there by using the glance_custom() extension mechanism. For this, you’ll need the development version from github:

    remotes::install_github("vincentarelbundock/modelsummary")
    

    Restart R entirely, then define a glance_custom.fixest() which includes a conditional check to delete the adj.r.squared value if it meets some condition. Here, we check if this is an instrumental variables model (bottom panel):

    library(fixest)
    library(modelsummary)
    
    cm <- c(
        "qsec" = "OLS",
        "fit_qsec" = "TSLS")
    
    panels <- list(
        "OLS" = list(
            "(I)" = feols(mpg ~ 1 + qsec, data = mtcars),
            "(II)" = feols(hp ~ 1 + qsec, data = mtcars)
        ),
        "TSLS" = list(
            "(I)" = feols(mpg ~ 1 | qsec ~ drat, data = mtcars),
            "(II)" = feols(hp ~ 1 | qsec ~ drat, data = mtcars)
        )
    )
    
    glance_custom.fixest <- function(x, ...) {
        if (isTRUE(x$iv)) {
            out <- data.frame("adj.r.squared" = NA)
        } else {
            out <- NULL
        }
        return(out)
    }
    
    modelsummary(
        panels,
        shape = "rbind",
        coef_map = cm,
        gof_map = c("nobs", "adj.r.squared"))
    
    (I) (II)
    OLS 1.412 -27.174
    (0.559) (4.946)
    Num.Obs. 32 32
    R2 Adj. 0.148 0.485
    TSLS 25.190 -188.788
    (47.992) (328.033)
    Num.Obs. 32 32