2013-02-23 20 views
17

Il mio obiettivo è quello di creare latextable con Multirow/caratteristiche più colonne da R. Il latextable voglio dovrebbe presentarsi così:R pacchetto XTABLE, come creare un latextable con più righe e colonne da R

   colLabel | colLabel2 
         | 
       a1 a2 | a3 a4 
------------------------------------- 
      b1 1 2 | 5  6 
rowLabel1    | 
      b2 3 4 | 7  8 
-------------------------------------- 
      b3 9 10 | 13 14 
rowLabel2    | 
      b4 11 12 | 15 16 
-------------------------------------- 

Attualmente sto usando xtable, ma non riesco a capire come creare multirow usando questo pacchetto. Qualcuno potrebbe dirmi come creare questo tavolo?

Grazie in anticipo

+0

vedono anche http://stackoverflow.com/questions/13984470/possible-to-create-latex-multicolumns-in-xtable/13985063#13985063 e http: // StackOverflow.it/questions/11950703/html-with-multicolumn-table-in-markdown-using-knitr – PaulHurleyuk

risposta

11

Dovrete essere più specifico su cosa esattamente si sta cercando di catalogare, ma credo che tabular funzione dal pacchetto tables potrebbe essere utile.

Ecco un esempio di mezzi tabulazione di una variabile in base alle 4 variabili fattore binarie:

mydf <- data.frame(rowFactor1 = sample(letters[1:2], 100, replace = TRUE), 
       colFactor1 = sample(LETTERS[1:2], 100, replace = TRUE), 
       x = rnorm(100), 
       rowFactor2 = sample(1:2, 100, replace = TRUE), 
       colFactor2 = sample(1:2, 100, replace = TRUE)) 

tab1 <- tabular(Heading()*RowFactor(rowFactor2, spacing = 1, 
         levelnames = c("rowLabel1", "rowLabel2"))* 
       Heading()*RowFactor(rowFactor1, 
         levelnames = c("b1", "b2")) ~ 
       Heading()*Factor(colFactor2, 
         levelnames = c("colLabel1", "colLabel2"))* 
       Heading()*Factor(colFactor1, 
         levelnames = c("a1", "a2"))* 
       Heading()*(x)*Heading()*(mean), 
     data = mydf) 

che ti dà qualcosa di simile, ma ben formattato quando si utilizza l'uscita lattice

               colLabel1   colLabel2   
                   a1  a2  a1  a2  
\\nopagebreak rowLabel1      \\nopagebreak b1 -0.1450 0.2633 0.91454 0.1222 
               \\nopagebreak b2 -0.1499 -0.4290 -0.09706 -0.6977 
\\rule{0pt}{1.7\\normalbaselineskip}rowLabel2 \\nopagebreak b1 0.6976 -0.4888 -0.68492 1.6764 
               \\nopagebreak b2 -0.2369 -0.1428 -0.66405 0.9469 

Infine latex(tab1) fornisce il codice latex:

\begin{tabular}{llcccc} 
\hline 
& & \multicolumn{2}{c}{colLabel1} & \multicolumn{2}{c}{colLabel2} \\ 
& & a1 & a2 & a1 & \multicolumn{1}{c}{a2} \\ 
\hline 
\nopagebreak rowLabel1 & \nopagebreak b1 & $-0.1450$ & $\phantom{-}0.2633$ & $\phantom{-}0.91454$ & $\phantom{-}0.1222$ \\ 
& \nopagebreak b2 & $-0.1499$ & $-0.4290$ & $-0.09706$ & $-0.6977$ \\ 
\rule{0pt}{1.7\normalbaselineskip}rowLabel2 & \nopagebreak b1 & $\phantom{-}0.6976$ & $-0.4888$ & $-0.68492$ & $\phantom{-}1.6764$ \\ 
& \nopagebreak b2 & $-0.2369$ & $-0.1428$ & $-0.66405$ & $\phantom{-}0.9469$ \\ 
\hline 
\end{tabular} 
1

Non posso aiutarti con le intestazioni delle colonne, ma per i valori di più righe in passato ho barato. La funzione qui sotto imposterà la seconda e le successive serie dello stesso valore da NA, e XTABLE poi non visualizzarli in modo da ottenere qualcosa che assomiglia vagamente ad un valore più fila (con la parte superiore giustificazione)

cleanf <- function(x){  
    oldx <- c(FALSE, x[-1]==x[-length(x)]) 
    # is the value equal to the previous?  
    res <- x 
    res[oldx] <- NA 
    return(res)} 
10

I desidero solo indicare una combinazione del blocco di Christoph's (here) e la risposta di Gabor nell'elenco di posta R (here) che funziona con il pacchetto xtable. Inoltre, questa soluzione è in grado di unire celle nel modo \multirow.

ecco che arriva un MWE:

require(xtable) 

# set up data frame 
df <- data.frame(c(replicate(2, c("L1")), replicate(2, c("L2"))), 
       replicate(4, "b"), 
       replicate(4, runif(4, 1, 10))) 

# only needed if first column consists of numbers 
df[[1]] <- as.character(df[[1]]) 

rle.lengths <- rle(df[[1]])$lengths 
first <- !duplicated(df[[1]]) 
df[[1]][!first] <- "" 

# define appearance of \multirow 
df[[1]][first] <- 
    paste0("\\midrule\\multirow{", rle.lengths, "}{*}{\\textbf{", df[[1]][first], "}}") 

strCaption <- paste0("\\textbf{Table Whatever} This table is just produced with some ", 
        "random data and does not mean anything. Just to show you how ", 
        "things work.") 

# set up xtable output 
print(xtable(df, digits = c(0, 0, 0, 3, 1, 0, 6), # first zero "represents" row numbers which we skip later 
      align = "lllrr|rr", # align and put a vertical line (first "l" again represents column of row numbers) 
      caption = strCaption, label = "testTable"), 
     size = "footnotesize", #Change size; useful for bigger tables "normalsize" "footnotesize" 
     include.rownames = FALSE, #Don't print rownames 
     include.colnames = FALSE, #We create them ourselves 
     caption.placement = "top", #"top", NULL 
     hline.after=NULL, #We don't need hline; we use booktabs 
     floating=TRUE, # whether \begin{Table} should be created (TRUE) or not (FALSE) 
     sanitize.text.function = force, # Important to treat content of first column as latex function 
     add.to.row = list(pos = list(-1, 
            2, 
            nrow(df)), 
         command = c(paste("\\toprule \n", # NEW row 
              "\\multicolumn{2}{c}{} & \\multicolumn{2}{c}{\\textbf{colLabel1}} & \\multicolumn{2}{c}{colLabel2} \\\\\n", 
              "\\cmidrule(l){3-4} \\cmidrule(l){5-6}\n", 
              " & & a1 & a2 & a3 & a4 \\\\\n", # NEW row 
              "\\midrule \n" 
             ), 
            paste("\\cmidrule(l){3-4} \\cmidrule(l){5-6}\n" # we may also use 'pos' and 'command' to add a midrule 
             ), 
            paste("\\bottomrule \n" # paste is used as it is more flexible regarding adding lines 
             ) 
            ) 
         ) 
    ) 

che lavora a maglia la seguente tabella in LaTeX:

enter image description here

+1

+1 Volevo solo aggiungere che 'print (..., booktabs = TRUE)' trasformerà automaticamente il tuo 'hline's in 'toprule',' midrule' e 'bottomrule'. – hplieninger

+0

soluzione meravigliosa, proprio come un promemoria per coloro che non hanno familiarità con LaTeX (come me), aggiungere '\ usepackage {multirow}' e '\ usepackage {booktabs}' per riprodurre questo (solo aiuto in \ multirow { } {} {}) –

1

Ecco un modo per farlo con il pacchetto huxtable (Io sono il autore):

library(huxtable) 
mydf <- data.frame(rowFactor1 = sample(letters[1:2], 100, replace = TRUE), 
    colFactor1 = sample(LETTERS[1:2], 100, replace = TRUE), 
    x = rnorm(100), 
    rowFactor2 = sample(1:2, 100, replace = TRUE), 
    colFactor2 = sample(1:2, 100, replace = TRUE)) 

tbl <- ftable(colFactor1 + colFactor2 ~ rowFactor1 + rowFactor2, data = mydf) 
ht <- as_hux(tbl) 

rowspan(ht)[c(4, 6), "V1"] <- 2 # these cells span 2 rows 
colspan(ht)[1, c(4, 6)] <- 2 # these cells span 2 columns 

ht[3, 1:2] <- '' # clean up some extraneous colum names 
ht[1:2, 3] <- '' 

right_border(ht)[,3] <- 1 
bottom_border(ht)[c(2, 5, 7), ] <- 1 
bottom_border(ht)[c(4,6), 1] <- 1 
ht 

Quando stampata al lattice Questo appare come:

huxtable pic

2

consideri il kableExtra package.

\documentclass{article} 
\usepackage{booktabs} 
\usepackage{multirow} 
\usepackage[table]{xcolor} 
\begin{document} 

<<setup, include=FALSE>>= 
library(knitr) 
opts_chunk$set(echo=FALSE) 
library(kableExtra) 
options(knitr.table.format = "latex") 
dat <- data.frame(
    group = c("rowLabel1", "rowLabel1", "rowLabel2", "rowLabel2"), 
    a1 = c(1, 3, 9, 11), 
    a2 = c(2, 4, 10, 12), 
    a3 = c(5, 7, 13, 15), 
    a4 = c(6, 8, 14, 16) 
) 
@ 

<<results='asis'>>= 
kable(dat, booktabs = TRUE, caption = "My table", escape = FALSE) %>% 
    add_header_above(c(" ", "colLabel1"=2, "colLabel2"=2)) %>% 
    kable_styling(latex_options = "hold_position") %>% 
    column_spec(1, bold=TRUE) %>% 
    collapse_rows(columns = 1) 
@ 

\end{document} 

enter image description here

Problemi correlati