lowndrul - 9 months ago 63

LaTeX Question

Q: How can I trim the extra horizontal rule length in LaTeX tables from R's

`xtable`

I'd like to do something like you see in my R code below. But that code throws and error, not producing the desired result.

`% table 1`

\begin{table}[ht]

\centering

\begin{tabular}{@{}lrr@{}}

\toprule

& a\_a & b\_b \\

\midrule

A & 0.35 & -1.05 \\

B & 0.64 & 0.92 \\

\bottomrule

\end{tabular}

\end{table}

% table 2

\begin{table}[ht]

\centering

\begin{tabular}{lrr}

\toprule

& a\_a & b\_b \\

\midrule

A & 0.36 & -1.05 \\

B & 0.64 & 0.92 \\

\bottomrule

\end{tabular}

\end{table}

`# Begin R code`

library(xtable)

library(stringr)

options(xtable.comment = FALSE)

set.seed(10)

mat <- matrix(rnorm(4), nrow=2)

rownames(mat) <- LETTERS[1:2]

colnames(mat) <- str_c(letters[1:2], "_", letters[1:2])

#mat.x <- xtable(mat, caption="My Caption!", align="lrr", digits=2) # No Error!

mat.x <- xtable(mat, align="@{}lrr@{}", digits=2) # Error!

print(mat.x,

sanitize.text.function = function(x){x},

sanitize.colnames.function = function(x){str_replace_all(x, "_", "\\\\_")},

floating=T,

hline.after=NULL,

math.style.negative=F,

add.to.row=list(pos=list(-1,0,nrow(mat.x)),

command=c("\\toprule ", "\\midrule ", "\\bottomrule ")))

# Error in `align<-.xtable`(`*tmp*`, value = "@{}lrr@{}") :

# "align" must have length equal to 3 ( ncol(x) + 1 )

# In addition: Warning message:

# In .alignStringToVector(value) : Nonstandard alignments in align string

Answer Source

You need to pass either a string with the same number of characters as the number of columns + 1, or a string of this length. So try (amongst other permutations)

```
align=c("@{}l", "r", "r@{}")
```

To see why have a look at the functions.

```
library(xtable)
set.seed(10)
mat <- matrix(rnorm(4), nrow=2)
rownames(mat) <- LETTERS[1:2]
colnames(mat) <- paste0(letters[1:2], "_", letters[1:2])
xtable(mat, align="@{}lrr@{}", digits=2)
```

"align" must have length equal to 3 ( ncol(x) + 1 )

The warning suggests passing a vector of length three, so try

```
xtable(mat, align=c("@{}l","r", "r@{}"), digits=2)
# \begin{table}[ht]
# \centering
# \begin{tabular}{@{}lrr@{}}
# ---
# ---
```

So that works as expected. Also the align argument is robust to how you pass the string, as long as it is of the required length.

```
xtable(mat, align=c("@{}lrr@", "{", "}"), digits=2)
# \begin{table}[ht]
# \centering
# \begin{tabular}{@{}lrr@{}}
# ---
# ---
```

To see why the first string didn't work
look at the relevant parts of `xtable:::xtable.data.frame`

function: must be to do with `align`

```
align(x) <- switch(1 + is.null(align), align, c("r", c("r", "l")[(characters | factors) + 1]))
```

This leads to `xtable:::`align<-.xtable`

, and then `xtable:::.alignStringToVector`