multiline table header using knitr and latex [duplicate] - r

This question already has answers here:
Simple example of using tables + knitr for latex
(2 answers)
Closed 7 years ago.
I ended up using tables package with knitr, but I can not figure out how to get a multiline header. Here is the code:
<<test_table, results='asis', echo=FALSE>>=
matrix <- matrix(1:9, nrow = 3)
colnames(matrix) <- c("first column", "seconf column which I want to have 2 lines because of its very long header title", "third column")
library(tables)
table <- as.tabular(matrix)
latex(table)
#

It's probably possible to do this with the tables package, but xtable provides a very easy solution. The following minimal example shows two different approaches:
\documentclass{article}
\begin{document}
<<setup, echo = FALSE>>=
library(xtable)
library(knitr)
opts_chunk$set(echo = FALSE, results = "asis")
matrix <- matrix(1:9, nrow = 3)
colnames(matrix) <- c(
"first column",
"second column which I want to have 2 lines because of its very long header title",
"third column")
#
<<ChangeColumnType>>=
print(xtable(matrix, align = c("r", "r", "p{4cm}", "r")), include.rownames = FALSE)
#
<<ChangeOnlyCell>>=
colnames(matrix)[2] <- "\\multicolumn{1}{p{4cm}}{second column which I want to have 2 lines because of its very long header title}"
print(xtable(matrix), include.rownames = FALSE, sanitize.colnames.function = identity)
#
\end{document}
The first approach (chunk ChangeColumnType) is very simple: It sets the column type of column 2 to p{4cm}. That gives a column that is 4cm wide with automatic text wrapping (see wikibooks.org for more details). The drawback is, that this affects the whole column, not only the cell in the first row.
The second approach (chunk ChangeOnlyCell) uses default alignment (or whatever you want to specify via align) and changes only the column type of the problematic cell using \multcolumn.
By default, xtable "sanitizes" your table, meaning that all special latex characters will be escaped. This is handy because you cannot (easily) break your TEX code, but here we manually want to inject LaTeX code, so we have to turn this off. Therefore, set sanitize.colnames.function = identiy. All column names will be used as you specify them – so be careful when using characters with a special meaning in LaTeX.
The example from above delivers the following tables:

Related

Replace column names in kable/R markdown

My data frame has ugly column names, but when displaying the table in my report, I want to their "real" names including special characters '(', new lines, greek letters, repeated names, etc.
Is there an easy way of replacing the names in knitr to allow such formatting?
Proposed solution
What I have tried to do is suppress the printing of the data frame names and use add_header_above for better names and names that span several columns. Some advice I've seen says to use:
x <- kable(df)
gsub("<thead>.*</thead>", "", x)
to remove the column names. That's fine, but the issue is that when I subsequently add_header_above, the original column names come back. If I use col.names=rep('',times=ncol(d.df)) in kable(...) the names are gone but the row remains, leaving a gap between my new column names and the table body. Here's a code chunk to illustrate:
```{r functions,echo=T}
drawTable <- function(d.df,caption='Given',hdr.above){
require(knitr)
require(kableExtra)
require(dplyr)
hdr.2 <- rep(c('Value','Rank'),times=ncol(d.df)/2)
x <- knitr::kable(d.df,format='latex',align='c',
col.names=rep('',times=ncol(d.df))) %>%
kable_styling(bootstrap_options=c('striped','hover',
'condensed','responsive'),position='center',
font_size = 9,full_width=F)
x %>% add_header_above(hdr.2) %>%
add_header_above(hdr.above)
}
```
```{r}
df <- data.frame(A=c(1,2),B=c(4,2),C=c(3,4),D=c(8,7))
hdr.above <- c('A2','B2','C2','D2')
drawTable(df,hdr.above = hdr.above)
```
I am not sure where you got the advice to replace rownames, but it seems excessively complex. It is much easier just to use the built-in col.names argument within kable. This solution works for both HTML and LaTeX outputs:
---
output:
pdf_document: default
html_document: default
---
```{r functions,echo=T}
require(knitr)
df <- data.frame(A=c(1,2),B=c(4,2),C=c(3,4),D=c(8,7))
knitr::kable(df,
col.names = c("Space in name",
"(Special Characters)",
"$\\delta{m}_1$",
"Space in name"))
```
PDF output:
HTML output:
If you're targeting HTML, then Δ is an option too.
I couldn't get the accepted answer to work on HTML, so used the above.

How to split kable over multiple columns?

I am trying to produce a "longitudinal" layout for long tables in RMarkdown with kable. For example, I would like a table to be split over two columns, like in the example below:
dd <- data.frame(state=state.abb, freq=1:50)
kable(list(state=dd[1:25,], state=dd[26:50,]))
However, this hack produces an output that looks a way worse than the normal kable output (for example the header is not in bold). Is there a "proper" way to do this using kable?
kable is a great tool, but has limits. For the type of table you're describing I would use one of two different tools depending on output wanted.
Hmisc::latex for .Rnw -> .tex -> .pdf
htmlTable::htmlTable for .Rmd -> .md -> .html
Here is an example of the latter:
dd <- data.frame(state=state.name, freq=1:50)
dd2 <- cbind(dd[1:25, ], dd[26:50, ])
library(htmlTable)
htmlTable(dd2,
cgroup = c("Set 1:25", "Set 26:50"),
n.cgroup = c(2, 2),
rnames = FALSE)
You can still use Kable with a slight modification to your code.
dd <- data.frame(state=state.abb, freq=1:50)
knitr::kable(
list(dd[1:25,], dd[26:50,]),
caption = 'Two tables placed side by side.',
booktabs = TRUE
)
This code is a modification of this. You can also find more information about tables on that page

Changing the decimal mark makes stargazer to put an extra space between numbers

I'm using the library stargazer to generate tables in latex (Rstudio/knitr/Sweave).
I need to change the decimal separator to comma (",") and the function stargazer() works most of the times. Only when the option summary = false is passed the results come with a extra space between numbers.
Anyone knows how to overcome this problem?
<<results='asis'>>=
library(stargazer)
set.seed(0)
x = matrix(rnorm(3),nrow = 1)
y = matrix(rnorm(9),nrow = 3)
stargazer(x,summary=FALSE)
stargazer(x,summary=FALSE,decimal.mark = ",")
stargazer(y,summary=TRUE,decimal.mark = ",")
#
Table 2 always shows a extra space between the comma and the first decimal place. Table 3 shows good results
When inspecting the generated TEX it becomes clear that stargazer does not add any spaces after the commas. The problem lies somewhere else:
The root of this problem is that LaTeX does not recognize , as a decimal separator by default. Therefore, when in math mode, LaTeX adds a space after each ,. This problem is described here on TEX.SE and the solution is to include the icomma package.
\documentclass{article}
\usepackage{icomma}
\begin{document}
<<results='asis', echo=FALSE, message = FALSE>>=
library(stargazer)
set.seed(0)
x = matrix(rnorm(3),nrow = 1)
y = matrix(rnorm(9),nrow = 3)
stargazer(x,summary=FALSE)
stargazer(x,summary=FALSE,decimal.mark = ",")
stargazer(y,summary=TRUE,decimal.mark = ",")
#
\end{document}
One question remains: Why was the problem not visible in Table 3 from the question? This is because stargazer uses inconsistent math markup in the tables. The second cell in Table 2 contains $$-$0,326$ whereas row 2, last column of Table 3 contains $-$0,006. In the first case, the number itself is in math mode, leading to the behavior described above. (And unfortunately, the - is in text mode, leading to bad typography.) In the second case, the number is in text mode, where no extra space is added.
To overcome the issue with the badly formatted minus signs, I recommend using xtable instead of stargazer for the simple (non-summary) tables. Combined with a custom column type that sets the column in math mode, the result is:
\documentclass{article}
\usepackage{icomma}
\usepackage{tabularx}
\newcolumntype{R}{>{$}r<{$}} % like an "r" column but in math mode
\begin{document}
<<results='asis', echo=FALSE>>=
library(xtable)
set.seed(0)
x = matrix(rnorm(3),nrow = 1)
print.xtable(
xtable(x, caption = "", align = rep("R", 4)),
include.rownames = FALSE,
include.colnames = FALSE,
format.args = list(decimal.mark = ","),
caption.placement = "top")
#
\end{document}

Wrapping pandoc table column names in r markdown

I am creating a pandoc.table with long column name that I want to wrap so my table does not go off the pdf page. I know you can use split.tables, but that takes away the clarity of the table. Using split.cells doesn't seem to do anything, even when supplied as a vector.
---
output : pdf_document
---
```{r,echo=FALSE, results="asis"}
library(pander)
mytab = data.frame(ReallySuperExtraLongColumnNameThatIWantToWrap=1:2, col2=2001:2002)
pandoc.table(mytab)
```
The following will produce a table with a line break in the header:
```{r,echo=FALSE, results="asis"}
library(pander)
mytab = data.frame("ReallySuperExtraLongColumn\nNameThatIWantToWrap"=1:2,
col2=2001:2002,
check.names = FALSE)
pandoc.table(mytab)
```
The line break is encoded with \n. This is not an allowed character in a columnname, and the data.frame() function would normally remove it. You can use check.names = FALSE to suppress this behaviour and keep the column names exactly as you entered them. Alternatively, you could redefine the column name on a separate line:
mytab = data.frame(ReallySuperExtraLongColumnNameThatIWantToWrap=1:2, col2=2001:2002)
names(mytab)[1] = "ReallySuperExtraLongColumn\nNameThatIWantToWrap"
You can also set the width of the cells with split.cells. The line breaks will then be generated automatically, however, breaks only appear when there is a space in your column header. An example:
```{r,echo=FALSE, results="asis"}
library(pander)
mytab = data.frame("Really Super Extra Long Column Name That I Want To Wrap"=1:2,
col2=2001:2002,
check.names = FALSE)
pandoc.table(mytab, split.cells = 15)
```
This gives breaks after "Extra" and "Name". Note that you still need check.names = FALSE, because also spaces are not allowed in data frame names.

Combine tables in R Markdown

I am trying to combine two tables in R Markdown into a single table, one below the other & retaining the header. The figure below shows the desired output. After putting my markdown code I will show the actual output. I realize that the way I have structured the pander statements will not allow me to get the output I want but searching SO I was unsuccessful in finding the right way to do so.
I can do some post processing in Word to get the output exactly as I want but I am trying to avoid that overhead.
The testdat.RData file is here: https://drive.google.com/file/d/0B0hTmthiX5dpWDd5UTdlbWhocVE/view?usp=sharing
The R Markdown RMD file is here: https://drive.google.com/file/d/0B0hTmthiX5dpSEFIcGRNQ1MzM1E/view?usp=sharing
Desired Output
```{r,echo=FALSE,message = FALSE, tidy=TRUE}
library(pander)
load("testdat.RData")
pander::pander(t1,big.mark=',', justify=c('left','right','right','right'))
pander::pander(t2,big.mark=',', justify=c('left','right','right','right'))
```
Actual Output
Thanks,
Krishnan
Here's my attempt using the xtable package:
```{r,echo=FALSE, message = FALSE, results="asis"}
library(xtable)
# Add thousands separator
t1[-1] = sapply(t1[-1], formatC, big.mark=",")
t2[-1] = sapply(t2[-1], formatC, big.mark=",")
t1$Mode = as.character(t1$Mode)
# Bind together t1, extra row of column names, and t2
t1t2 = rbind(t1, names(t1), t2)
# Render the table using xtable
print(xtable(t1t2, align="rrrrr"), # Right-align all columns (includes extra value for row names)
include.rownames=FALSE, # Don't print rownames
hline.after=NULL,
# Add midrules before/after each set column names
add.to.row = list(pos = list(-1,0,4,5),
command = rep("\\midrule \n",4)))
```
And here's the output:
Allow me to make a formal answer since my comment seemed to work for you.
pander(rbind(t1,names(t2),t2))

Resources