HTML with multicolumn table in Markdown using knitr
Ok, so I wrote it myself...
The package is as of version 1.0 called htmlTable and is available both from CRAN and and my blog, gforge.se/packages. I hope you find it useful. I've created a few vignettes to help with all the options.
Have two columns in Markdown
You can't, at least not with pure Markdown as it doesn't have any concept of columns. As explained in the rules:
The idea for Markdown is to make it easy to read, write, and edit prose. HTML is a publishing format; Markdown is a writing format. Thus, Markdown’s formatting syntax only addresses issues that can be conveyed in plain text.
For any markup that is not covered by Markdown’s syntax, you simply use HTML itself.
In fact, the best way would be to have each code block wrapped in a <div>
with the appropriate class assigned to each div. However, most Markdown parsers do not parse Markdown inside a raw HTML block. Therefore, you may need to also define the code block in raw HTML as well. Check your parser's list of features to find out. In the event you are not able to define your own CSS to use separately from the Markdown (to style the HTML), you will also need to define the styles inline in the HTML. This question includes a nice sample of what that might look like. Just replace the comments with the appropriate code blocks. If you have to define your code blocks in raw HTML, they would look like this:
<pre><code class="language-c">int foo (void)
{
int i;
}
</code></pre>
So, the final document that is sure to work in all (most?) Markdown parsers would look like this:
# Rule 1
Description for rule 1.
<div style="-webkit-column-count: 2; -moz-column-count: 2; column-count: 2; -webkit-column-rule: 1px dotted #e0e0e0; -moz-column-rule: 1px dotted #e0e0e0; column-rule: 1px dotted #e0e0e0;">
<div style="display: inline-block;">
<h2>Good</h2>
<pre><code class="language-c">int foo (void)
{
int i;
}
</code></pre>
</div>
<div style="display: inline-block;">
<h2>Bad</h2>
<pre><code class="language-c">int foo (void) {
int i;
}
</code></pre>
</div>
</div>
Note that that uses one of many different ways of defining columns in CSS. Different methods may or may not work in different browsers. YMMV.
Create a LaTeX style table in Markdown with colors
The problem is that rmarkdown automatically loads the xcolor
package way before it inserts the header-includes
, so you don't have a chance to influence the package options there.
As a workaround, you can define table
as class option, which will then be passed to all packages, including the xcolor
package (and hope for the best that it won't cause any problems in other packages...)
---
title: "misc"
author: "Me"
date: "`r Sys.Date()`"
output:
pdf_document:
keep_tex: true
extra_dependencies: caption
number_sections: yes
fig_caption: yes
classoption: table
header-includes:
- \usepackage{float}
- \usepackage{framed}
- \usepackage{fontawesome}
- \usepackage{caption}
- \usepackage{multirow}
fontsize: 11pt
urlcolor: blue
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{=latex}
\begin{table}[htbp]
\begin{tabular}{|
>{\columncolor[HTML]{656565}}c |lcccc|}
\hline
\cellcolor[HTML]{656565}{\color[HTML]{FFFFFF} } & \multicolumn{5}{c|}{\cellcolor[HTML]{656565}{\color[HTML]{FFFFFF} Type of Distribution}} \\ \cline{2-6}
\cellcolor[HTML]{656565}{\color[HTML]{FFFFFF} } & \multicolumn{1}{l|}{} & \multicolumn{1}{l|}{Lognormal} & \multicolumn{1}{l|}{Exponential} & \multicolumn{1}{l|}{Gamma} & \multicolumn{1}{l|}{Weibull} \\ \cline{2-6}
\cellcolor[HTML]{656565}{\color[HTML]{FFFFFF} } & \multicolumn{1}{l|}{Box-Cox} & \multicolumn{1}{c|}{Y} & \multicolumn{1}{c|}{Y} & \multicolumn{1}{c|}{\cellcolor[HTML]{9B9B9B}\textbf{Y}} & \cellcolor[HTML]{9B9B9B}\textbf{Y} \\ \cline{2-6}
\cellcolor[HTML]{656565}{\color[HTML]{FFFFFF} } & \multicolumn{1}{l|}{Exponential} & \multicolumn{1}{c|}{Y} & \multicolumn{1}{c|}{Y} & \multicolumn{1}{c|}{Y} & Y \\ \cline{2-6}
\cellcolor[HTML]{656565}{\color[HTML]{FFFFFF} } & \multicolumn{1}{l|}{Simple power} & \multicolumn{1}{c|}{Y} & \multicolumn{1}{c|}{\cellcolor[HTML]{9B9B9B}\textbf{Y}} & \multicolumn{1}{c|}{\cellcolor[HTML]{9B9B9B}\textbf{Y}} & \cellcolor[HTML]{9B9B9B}\textbf{Y} \\ \cline{2-6}
\multirow{-6}{*}{\cellcolor[HTML]{656565}{\color[HTML]{FFFFFF} \begin{tabular}[c]{@{}c@{}}Type of\\ transformation\end{tabular}}} & \multicolumn{1}{l|}{Logarithmic} & \multicolumn{1}{c|}{\cellcolor[HTML]{9B9B9B}\textbf{Y}} & \multicolumn{1}{c|}{Y} & \multicolumn{1}{c|}{\cellcolor[HTML]{9B9B9B}\textbf{N}} & \cellcolor[HTML]{9B9B9B}\textbf{N} \\ \hline
\end{tabular}
\end{table}
```
How to split kable over multiple columns?
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)
knitr printing list of data.frames with each table on new page
You can use purrr::imap
to get the index in the .y
variable:
``` r
library(kableExtra)
library(tidyverse)
library(purrr)
mt1 <-
matrix(
data = runif(n = 200, min = 101, max = 999)
,
nrow = 20
,
ncol = 10
,
byrow = TRUE
,
dimnames = list(LETTERS[1:20], paste0("V", 1:10))
)
df1 <- data.frame(Name = row.names(mt1), mt1)
dfs <-
unname(split.default(df1[,-1], as.integer(gl(
ncol(df1) - 1, 5, ncol(df1) - 1
))))
f <- function() {
for (i in 1:length(dfs)) {
print(
kable(
cbind(df1[1], dfs[i])
,
format = 'latex'
,
row.names = FALSE
) %>%
row_spec(
row = c(0),
bold = TRUE,
italic = TRUE,
align = "l"
)
)
if (i < length(dfs)) {
cat("\n\n\\newpage\n")
}
}
}
f_map <- function() {
invisible(dfs %>% purrr::imap(~ {
print(
kable(cbind(df1[1], .x)
, format = 'latex'
, row.names = FALSE) %>%
row_spec(
row = c(0),
bold = TRUE,
italic = TRUE,
align = "l"
)
#cat("\n\n\\newpage\n")
)
if (.y < length(dfs))
cat("\n\n\\newpage\n")
}))
}
identical(capture.output(f()), capture.output(f_map()))
#> [1] TRUE
microbenchmark::microbenchmark( f = {res <- capture.output(f())}, f_map = {res <- capture.output(f_map())})
#> Unit: milliseconds
#> expr min lq mean median uq max neval cld
#> f 7.908510 8.431997 9.662659 9.012099 10.10318 15.42358 100 a
#> f_map 7.983586 8.462561 9.797256 9.150356 10.71692 16.20676 100 a
```
<sup>Created on 2020-07-23 by the [reprex package](https://reprex.tidyverse.org) (v0.3.0)</sup>
As stated by @CL, this is not faster nor shorter than a simple loop.
How make 2 column layout in R markdown when rendering pdf?
New pandoc version have made this easier since my original answer. According to pandoc's manual, you can now specify classoptions directly in the YAML front matter:
---
classoption:
- twocolumn
---
The new div notation also allows for inserting two column sections anywhere in the document, working for most formats
:::::::::::::: {.columns}
::: {.column width="40%"}
contents...
:::
::: {.column width="60%"}
contents...
:::
::::::::::::::
Original answer
You can use the article option twocolumn
to format the whole document in two columns. Add this to your yaml front matter:
---
output:
pdf_document:
pandoc_args: [
"-V", "classoption=twocolumn"
]
---
Related Topics
R Column Check If Contains Value from Another Column
How Many Non-Na Values in Each Row for a Matrix
Which Library Could Be Used to Make a Chord Diagram in R
How to Remove "Rows" with a Na Value
How to Save a Data Frame as CSV to a User Selected Location Using Tcltk
How to Convert Utm Coordinates to Lat and Long in R
Updating Column in One Dataframe with Value from Another Dataframe Based on Matching Values
Real Time, Auto Updating, Incremental Plot in R
How to Get Code Completion for R in Emacs Ess Similar to What Is Available in Rstudio
R Aggregate Data in One Column Based on 2 Other Columns
Evaluate (I.E., Predict) a Smoothing Spline Outside R
Increase Legend Font Size Ggplot2
Figures Captions and Labels in Knitr
Controlling the 'Alpha' Level in a Ggplot2 Legend
Download Attachment from an Outlook Email Using R