Search code examples
rlatexlinear-regressionstatsmodels

Table with customs stars and standard error BELOW coefficient estimated


I am manually generating a model-summary table that includes parameter estimates, standard errors, and custom stars. Unfortunately, I want to have the standard errors BELOW the parameters estimates and not NEXT TO it. My final goal is to export it to LaTeX. Now I am using xtable() to do it.

Please gently consider the following example with the corresponding desired output.

Example structure

#example betas and sd
b<- structure(c(1.5, 3.5, 1.4), .Dim = c(3L,1L), .Dimnames = list(c("beta_x1", "beta_x2","beta_x3"), "Parameters"))
sd<- structure(c(0.02, 15.0, 1.025), .Dim = c(3L,1L), .Dimnames = list(c("se.beta_x1", "se.beta_x2","se.beta_x3"), "Sd"))
# example p-values
p_val <- as.numeric(pt(q = abs(b/sd),d= 1000 , lower=FALSE))
star_fn <- function(x){
  out <- ifelse(x <= 0.1, ifelse(x <= 0.05, ifelse(x <= 0.01, "***", "**"), '*'), "")
  out
}
# Generating Stars
stars <- star_fn(p_val)
# Table (to LaTeX)
tab<- cbind(Coef = format(b,digits = 3),sd = paste("(", sprintf("%.3f", sd), ")", sep=""), Stars =stars)
tab
        Parameters    sd      Stars
beta_x1 "1.5"      "(0.020)"  "***"
beta_x2 "3.5"      "(15.000)" ""   
beta_x3 "1.4"      "(1.025)"  "*" 

library(xtable)
xtable(tab)

Desired Output

structure(list(Name = c("beta_x1", " ", "beta_x2", " ", "beta_x3", 
                        " "), Coef = c("1.5***", "(0.020)", "3.5", "(15.000)", "1.4*", 
                                       "(1.025)")), row.names = c(NA, -6L), class = "data.frame")


  Name     Coef
1 beta_x1   1.5***
2          (0.020)
3 beta_x2      3.5
4         (15.000)
5 beta_x3     1.4*
6          (1.025)

xtable(tab)

Solution

  • here is an option where we convert the matrix to data.frame, get the row.names as a column, pivot to long format and replace the duplicated elements in 'Name' to blank ('')

    library(dplyr)
    library(tidyr)
    library(tibble)
    tab %>% 
      as.data.frame %>% 
      rownames_to_column('Name') %>% 
      unite(Coef, Parameters, Stars, sep="") %>%
      pivot_longer(cols = -Name, values_to = 'Coef') %>% 
      select(-name) %>%
      mutate(Name = replace(Name, duplicated(Name), ""))
    

    -output

    # A tibble: 6 x 2
    #  Name      Coef    
    #  <chr>     <chr>   
    #1 "beta_x1" 1.5***  
    #2 ""        (0.020) 
    #3 "beta_x2" 3.5     
    #4 ""        (15.000)
    #5 "beta_x3" 1.4*    
    #6 ""        (1.025)