rmergechi-squared

Merging multiple chi square tables into one big table


This is a follow-up question inspired by dcarlson's answer to the question "Why is the Chi Square Expected vs Observed in two different structures?"

I have 3x flat tables (NN & BB & FF) showing Chi-Square results (Observed & Expected frequencies).

NN <- as.table(rbind(c(11, 25), c(32, 27)))
dimnames(NN) <- list(gender = c("Top", "Other"),
                    source = c("You","Partner"))
(Xsq_NN <- chisq.test(NN))

NN_Results <- array(cbind(Xsq_NN$observed, Xsq_NN$expected), dim=c(2, 2, 2), 
                   dimnames=list(Rank = c("Top", "Other"),
                                 Source = c("You", "Partner"), 
                                 c("Observed", "Expected")))
options(digits=3)
ftable(NN_Results, row.vars=1, col.vars=2:3)

BB <- as.table(rbind(c(11, 29), c(32, 23)))
dimnames(BB) <- list(gender = c("Top", "Other"),
                     source = c("You","Partner"))
(Xsq_BB <- chisq.test(BB))

BB_Results <- array(cbind(Xsq_BB$observed, Xsq_BB$expected), dim=c(2, 2, 2), 
                   dimnames=list(Rank = c("Top", "Other"),
                                 Source = c("You", "Partner"), 
                                 c("Observed", "Expected")))
options(digits=3)
ftable(BB_Results, row.vars=1, col.vars=2:3)

FF <- as.table(rbind(c(6, 5), c(37, 47)))
dimnames(FF) <- list(gender = c("Top", "Other"),
                     source = c("You","Partner"))
(Xsq_FF <- chisq.test(FF))

FF_Results <- array(cbind(Xsq_FF$observed, Xsq_FF$expected), dim=c(2, 2, 2), 
                   dimnames=list(Rank = c("Top", "Other"),
                                 Source = c("You", "Partner"), 
                                 c("Observed", "Expected")))
options(digits=3)
ftable(FF_Results, row.vars=1, col.vars=2:3)

I am greatly struggling to now merge the three tables, however keeping and adding headers to the columns.

This is the attempt:

# Name contingency tables
NN_table <- ftable(NN_Results, row.vars = 1, col.vars = 2:3)
BB_table <- ftable(BB_Results, row.vars = 1, col.vars = 2:3)
FF_table <- ftable(FF_Results, row.vars = 1, col.vars = 2:3)

# Combine the tables horizontally
Merged_Table <- cbind(NN_table, BB_table, FF_table)

# Print the merged table
print(Merged_Table)

> Merged_Table
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,]   11 16.3   25 19.7   11 18.1   29 21.9    6  4.98     5  6.02
[2,]   32 26.7   27 32.3   32 24.9   23 30.1   37 38.02    47 45.98

My problem is that I now have all the headers lost... I would like to have column headers to hopefully look like this: Goal Layout

Finally, I would like to add the chi-square (p-value) below per item/column: enter image description here

Thankful for any help!


Solution

  • I usually make this kind of table using the flextable package

    # Combine the tables horizontally
    Merged_Table <- cbind(NN_table, BB_table, FF_table)
    
    # From your Merged_Table we add the p.values and colnames
    Merged_p <-
      as.data.frame(rbind(round(Merged_Table,2),
                          rep(
                            paste0(
                              round(c(Xsq_NN$statistic, Xsq_BB$statistic, Xsq_FF$statistic),2), " (",
                              round(c(Xsq_NN$p.value, Xsq_BB$p.value, Xsq_FF$p.value),3), ")"
                            )
                            , each = 4)))
    
    # Making the table names
    colnames(Merged_p) <- paste( 
       rep(c("NN", "BB", "FF"), each = 4 ),
       rep(c("You","You","Partner","Partner"), 3),
       rep(c("Observed","Expected"), 6), sep = "_" )
    
    Merged_p <- cbind(" " = c("Top","Other","Chi-2 (p-value)"), Merged_p)
    
    library(flextable)
    
    your_table <- 
    flextable(Merged_p) |>
      ftExtra::span_header() |>
      theme_booktabs()|>
      merge_h() |> 
      hline(i = c(1,2,3),part = 'header') |>
      vline(j = seq(1,13, by = 2)) |>
      align(align = 'center', part = 'all')
    
    # Print the merged table with p-values
    # print(your_table)
    

    enter image description here