Search code examples
rcrosstabxtable

R:CrossTable- How to print frequencies for total row and column observations with xtable?


I produced a cross table with the CrossTable command from the gmodels package such as:

library(gmodels)
library(descr)
a<-CrossTable(mtcars$cyl,mtcars$gear,prop.chisq = FALSE)

If I create a table for LaTex using xtable, the frequencies for row totals (last column) and column totals (last row) are missing. However, the total counts are there.

I used:

print(xtable(a,digits=3))

to achieve this. How do I get these values in as well?

Thanks for your support.

EDIT:

Here an example of the output:

a

===========================================
          mtcars$gear
mtcars$cyl        3       4       5   Total
-------------------------------------------
4                 1       8       2      11
              0.091   0.727   0.182   **0.344**
              0.067   0.667   0.400        
              0.031   0.250   0.062        
-------------------------------------------
6                 2       4       1       7
              0.286   0.571   0.143   **0.219**
              0.133   0.333   0.200        
              0.062   0.125   0.031        
-------------------------------------------
8                12       0       2      14
              0.857   0.000   0.143   **0.438**
              0.800   0.000   0.400        
              0.375   0.000   0.062        
-------------------------------------------
Total            15      12       5      32
              **0.469**   **0.375**   **0.156**
===========================================

I highlighted the missing values after xtable conversion with *. But when I have it converted to Tex with print it looks like:

\begin{table}[ht]
\centering
\begin{tabular}{llrrrr}
  \hline
 & mtcars\$cyl & 3 & 4 & 5 & Total \\ 
  \hline
1 & 4 & 1 & 8 & 2 & 11 \\ 
  2 &  & 0.091 & 0.727 & 0.182 &  \\ 
 3 &  & 0.067 & 0.667 & 0.400 &  \\ 
 4 &  & 0.031 & 0.250 & 0.062 &  \\ 
 5 & 6 & 2 & 4 & 1 & 7 \\ 
 6 &  & 0.286 & 0.571 & 0.143 &  \\ 
 7 &  & 0.133 & 0.333 & 0.200 &  \\ 
 8 &  & 0.062 & 0.125 & 0.031 &  \\ 
 9 & 8 & 12 & 0 & 2 & 14 \\ 
  10 &  & 0.857 & 0.000 & 0.143 &  \\ 
  11 &  & 0.800 & 0.000 & 0.400 &  \\ 
  12 &  & 0.375 & 0.000 & 0.062 &  \\ 
  13 & Total & 15 & 12 & 5 & 32 \\ 
   \hline
\end{tabular}
\end{table}

Solution

  • This could be viewed as a bug in the xtable.Crosstable method, which is in the descr package

    environment(getS3method("xtable", "CrossTable"))
    <environment: namespace:descr>
    

    So you might like to contact the package maintainer about this. Meanwhile here is a hack that avoids re-computing the proportions yourself.

    First capture the printed output from xtable to a temporary file and read each line back in as a separate string:

    file <- tempfile()
    capture.output(print(xtable(a, digits=3), include.rownames = FALSE),
                   file = file)
    xout <- readLines(file)
    

    I have assumed you don't want the rownames in your table. Do the same for the printed version of the CrossTable:

    capture.output(CrossTable(mtcars$cyl,mtcars$gear,prop.chisq = FALSE),
               file = file)
    out <- readLines(file)
    

    Next extract the body of the printed CrossTable output and "LaTeXize" it

    body <- out[11:29]
    ## replace whitespace by column delimiter
    body <- gsub("  *", " & ", body)
    ## add end of line markup for table rows
    body <- gsub("([^-])$", "\\1 \\\\\\\\", body)
    ## replace dashed lines with hline
    body <- gsub("-+", "\\\\hline", body)
    ## replace $ with \$
    body <- gsub("$", "\\$", body, fixed = TRUE)
    

    Finally print the header and footer from the printed xtable output with the new body:

    cat(xout[1:6], body, xout[22:24], sep = "\n")
    

    Producing the output

    % latex table generated in R 3.1.1 by xtable 1.7-4 package
    % Tue Oct 14 12:17:07 2014
    \begin{table}[ht]
    \centering
    \begin{tabular}{lrrrr}
      \hline
    mtcars\$cyl & 3 & 4 & 5 & Total \\
    \hline
    4 & 1 & 8 & 2 & 11 \\
     & 0.091 & 0.727 & 0.182 & 0.344 \\
     & 0.067 & 0.667 & 0.400 &  \\
     & 0.031 & 0.250 & 0.062 &  \\
    \hline
    6 & 2 & 4 & 1 & 7 \\
     & 0.286 & 0.571 & 0.143 & 0.219 \\
     & 0.133 & 0.333 & 0.200 &  \\
     & 0.062 & 0.125 & 0.031 &  \\
    \hline
    8 & 12 & 0 & 2 & 14 \\
     & 0.857 & 0.000 & 0.143 & 0.438 \\
     & 0.800 & 0.000 & 0.400 &  \\
     & 0.375 & 0.000 & 0.062 &  \\
    \hline
    Total & 15 & 12 & 5 & 32 \\
     & 0.469 & 0.375 & 0.156 \\
    \hline
    \end{tabular}
    \end{table}