Search code examples
rlatextexxtable

combine multiple xtables in R


I would like to combine 2 dataset, when I run code below in R, however doesn't show the headers and I would like to see the column header for each dataset

 iriss <- head(iris)
    iriss1 <- tail(iris)
   print(xtable(rbind(iriss,iriss1)))

expected output is this, how can i get this from R console?

\begin{table}[ht]
    \centering
    \begin{tabular}{rrrrrl}
        \hline
        & Sepal.Length & Sepal.Width & Petal.Length & Petal.Width & Species \\ 
        \hline
        1 & 5.10 & 3.50 & 1.40 & 0.20 & setosa \\ 
        2 & 4.90 & 3.00 & 1.40 & 0.20 & setosa \\ 
        3 & 4.70 & 3.20 & 1.30 & 0.20 & setosa \\ 
        4 & 4.60 & 3.10 & 1.50 & 0.20 & setosa \\ 
        5 & 5.00 & 3.60 & 1.40 & 0.20 & setosa \\ 
        6 & 5.40 & 3.90 & 1.70 & 0.40 & setosa \\ 
        \hline
        & Sepal.Length & Sepal.Width & Petal.Length & Petal.Width & Species \\ 
        \hline
        145 & 6.70 & 3.30 & 5.70 & 2.50 & virginica \\ 
        146 & 6.70 & 3.00 & 5.20 & 2.30 & virginica \\ 
        147 & 6.30 & 2.50 & 5.00 & 1.90 & virginica \\ 
        148 & 6.50 & 3.00 & 5.20 & 2.00 & virginica \\ 
        149 & 6.20 & 3.40 & 5.40 & 2.30 & virginica \\ 
        150 & 5.90 & 3.00 & 5.10 & 1.80 & virginica \\ 
        \hline
    \end{tabular}
\end{table}

many thanks in advance


Solution

  • An xtable is essentially a data frame with a printing method that shows the latex code for reproducing the table in a latex document. It is therefore not possible to create an xtable object that prints the way you want it to.

    However, it is possible to get the desired output to the console by capturing the console output and manipulating it to join multiple tables together. Here is a function that will do it:

    multi_xtable <- function(...)
    {
      vars <- as.list(match.call(expand.dots = TRUE))[-1]
      df_list <- lapply(vars, eval)
      num_cols <- sapply(df_list, length)
      if (!all(num_cols == num_cols[1]))
        stop("All data frames must have equal number of columns")  
      xtables <- lapply(df_list, function(x) capture.output(xtable::xtable(x)))
      if (length(xtables) == 1) 
        return(xtables[[1]])  
      header <- xtables[[1]][1:6]
      tail <- xtables[[1]][length(xtables[[1]]) + (-1:0)]
      xtables <- lapply(xtables, function(x) x[7:(length(x) - 2)])
      xtables <- do.call("c", xtables)  
      cat(header, xtables, tail, sep = "\n")
    }
    

    And you can use it like this:

    multi_xtable(iriss, iriss1)
    #> % latex table generated in R 3.6.2 by xtable 1.8-4 package
    #> % Wed Apr 29 12:51:24 2020
    #> \begin{table}[ht]
    #> \centering
    #> \begin{tabular}{rrrrrl}
    #>   \hline
    #>  & Sepal.Length & Sepal.Width & Petal.Length & Petal.Width & Species \\ 
    #>   \hline
    #> 1 & 5.10 & 3.50 & 1.40 & 0.20 & setosa \\ 
    #>   2 & 4.90 & 3.00 & 1.40 & 0.20 & setosa \\ 
    #>   3 & 4.70 & 3.20 & 1.30 & 0.20 & setosa \\ 
    #>   4 & 4.60 & 3.10 & 1.50 & 0.20 & setosa \\ 
    #>   5 & 5.00 & 3.60 & 1.40 & 0.20 & setosa \\ 
    #>   6 & 5.40 & 3.90 & 1.70 & 0.40 & setosa \\ 
    #>    \hline
    #>  & Sepal.Length & Sepal.Width & Petal.Length & Petal.Width & Species \\ 
    #>   \hline
    #> 145 & 6.70 & 3.30 & 5.70 & 2.50 & virginica \\ 
    #>   146 & 6.70 & 3.00 & 5.20 & 2.30 & virginica \\ 
    #>   147 & 6.30 & 2.50 & 5.00 & 1.90 & virginica \\ 
    #>   148 & 6.50 & 3.00 & 5.20 & 2.00 & virginica \\ 
    #>   149 & 6.20 & 3.40 & 5.40 & 2.30 & virginica \\ 
    #>   150 & 5.90 & 3.00 & 5.10 & 1.80 & virginica \\ 
    #>    \hline
    #> \end{tabular}
    #> \end{table}