This function maps columns from the input data, x, to htmlTable() parameters.
It's designed to provide a fluent interface for those familiar with the tidyverse ecosystem.
tidyHtmlTable(
x,
value,
header,
rnames,
rgroup,
hidden_rgroup,
cgroup,
tspanner,
hidden_tspanner,
skip_removal_warning = getOption("htmlTable.skip_removal_warning", FALSE),
rnames_unique,
table_fn = htmlTable,
...
)Tidy data used to build the htmlTable
Column containing values for individual table cells. Defaults to "value" (same as tidyr::pivot_wider).
Column in x specifying column headings
Column in x specifying row names. Defaults to "name" (same as tidyr::pivot_wider()).
Column in x specifying row groups.
Strings indicating rgroup values to be hidden.
Columns in x specifying the column groups.
Column in x specifying tspanner groups.
Strings indicating tspanner values to be hidden.
Boolean to suppress warnings when removing NA columns.
Designates unique row names when regular names lack uniqueness.
Function to format the table, defaults to htmlTable().
Additional arguments passed to htmlTable().
Returns the HTML code that, when rendered, displays a formatted table.
Columns from x are mapped (transformed) to specific parameters of the htmlTable()
The following columns are converted to match the intended input structure:
value
header
rnames
rgroup
cgroup
tspanner
Each combination of the variables in x should be unique to map correctly to the output table.
Usually each row should have a unique combination of the mappers. Sometimes though rows come in a distinct order and the order identifies the row more than the name. E.g. if we are identifying bone fractures using the AO-classification we will have classes ranging in the form of:
A
A1
A1.1
A2
A2.1
A2.2
B
...
we can simplify the names while retaining the key knowledge to:
A
.1
...1
.2
...1
...2
B
...
This will though result in non-unique rows and thus we need to provide the original
names in addition to the rnames argument. To do this we have rnames_unique as a parameter,
without this tidyHtmlTable we risk unintended merging of cells, generating > 1 value per cell.
Note it is recommended that you verify with the full names just to make sure that any unexpected row order change has happened in the underlying pivot functions.
Rows can be pre-sorted using dplyr::arrange() before passing to tidyHtmlTable.
Column sorting is based on arrange(cgroup, header). If you want to sort in non-alphabetic
order you can provide a factor variable and that information will be retained.
The tibble discourages the use of row names. There is therefore a convenience
option for tidyHtmlTable where you can use the function just as you
would with htmlTable() where rnames is populated with
the rnames argument provided using tidyselect syntax (defaults to
the "names" column if present int the input data).
In order to run this function you also must have dplyr, tidyr, tidyselect and purrr packages installed. These have been removed due to the additional 20 Mb that these dependencies added (issue #47). Note: if you use tidyverse it will already have all of these and you do not need to worry.
library(tibble)
library(dplyr)
#>
#> Attaching package: ‘dplyr’
#> The following objects are masked from ‘package:stats’:
#>
#> filter, lag
#> The following objects are masked from ‘package:base’:
#>
#> intersect, setdiff, setequal, union
library(tidyr)
#>
#> Attaching package: ‘tidyr’
#> The following object is masked from ‘package:magrittr’:
#>
#> extract
# Prep and select basic data
data("mtcars")
base_data <- mtcars %>%
rownames_to_column() %>%
mutate(gear = paste(gear, "Gears"),
cyl = paste(cyl, "Cylinders")) %>%
select(rowname, cyl, gear, wt, mpg, qsec)
base_data %>%
pivot_longer(names_to = "per_metric",
cols = c(wt, mpg, qsec)) %>%
group_by(cyl, gear, per_metric) %>%
summarise(value_Mean = round(mean(value), 1),
value_Min = round(min(value), 1),
value_Max = round(max(value), 1),
.groups = "drop") %>%
pivot_wider(names_from = per_metric,
values_from = starts_with("value_")) %>%
# Round the values into a nicer format where we want the weights to have two decimals
txtRound(ends_with("_wt"), digits = 2) %>%
txtRound(starts_with("value") & !ends_with("_wt"), digits = 1) %>%
# Convert into long format
pivot_longer(cols = starts_with("value_"), names_prefix = "value_") %>%
separate(name, into = c("summary_stat", "per_metric")) %>%
# Without sorting the row groups wont appear right
# If the columns end up in the wrong order you may want to change the columns
# into factors
arrange(per_metric) %>%
addHtmlTableStyle(align = "r") %>%
tidyHtmlTable(
header = gear,
cgroup = cyl,
rnames = summary_stat,
rgroup = per_metric,
skip_removal_warning = TRUE)
#> <table class='gmisc_table' style='border-collapse: collapse; margin-top: 1em; margin-bottom: 1em;' >
#> <thead>
#> <tr>
#> <th style='border-top: 2px solid grey;'></th>
#> <th colspan='3' style='font-weight: 900; border-bottom: 1px solid grey; border-top: 2px solid grey; text-align: center;'>4 Cylinders</th><th style='border-bottom: none; border-top: 2px solid grey;' colspan=1> </th>
#> <th colspan='3' style='font-weight: 900; border-bottom: 1px solid grey; border-top: 2px solid grey; text-align: center;'>6 Cylinders</th><th style='border-bottom: none; border-top: 2px solid grey;' colspan=1> </th>
#> <th colspan='2' style='font-weight: 900; border-bottom: 1px solid grey; border-top: 2px solid grey; text-align: center;'>8 Cylinders</th>
#> </tr>
#> <tr><th style='border-bottom: 1px solid grey;'></th>
#> <th style='font-weight: 900; border-bottom: 1px solid grey; text-align: center;'>3 Gears</th>
#> <th style='font-weight: 900; border-bottom: 1px solid grey; text-align: center;'>4 Gears</th>
#> <th style='font-weight: 900; border-bottom: 1px solid grey; text-align: center;'>5 Gears</th>
#> <th style='font-weight: 900; border-bottom: 1px solid grey; text-align: center;' colspan=1> </th>
#> <th style='font-weight: 900; border-bottom: 1px solid grey; text-align: center;'>3 Gears</th>
#> <th style='font-weight: 900; border-bottom: 1px solid grey; text-align: center;'>4 Gears</th>
#> <th style='font-weight: 900; border-bottom: 1px solid grey; text-align: center;'>5 Gears</th>
#> <th style='font-weight: 900; border-bottom: 1px solid grey; text-align: center;' colspan=1> </th>
#> <th style='font-weight: 900; border-bottom: 1px solid grey; text-align: center;'>3 Gears</th>
#> <th style='font-weight: 900; border-bottom: 1px solid grey; text-align: center;'>5 Gears</th>
#> </tr>
#> </thead>
#> <tbody>
#> <tr><td colspan='11' style='font-weight: 900;'>mpg</td></tr>
#> <tr>
#> <td style='text-align: left;'> Mean</td>
#> <td style='text-align: right;'>21.5</td>
#> <td style='text-align: right;'>26.9</td>
#> <td style='text-align: right;'>28.2</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>19.8</td>
#> <td style='text-align: right;'>19.8</td>
#> <td style='text-align: right;'>19.7</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>15.1</td>
#> <td style='text-align: right;'>15.4</td>
#> </tr>
#> <tr>
#> <td style='text-align: left;'> Min</td>
#> <td style='text-align: right;'>21.5</td>
#> <td style='text-align: right;'>21.4</td>
#> <td style='text-align: right;'>26.0</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>18.1</td>
#> <td style='text-align: right;'>17.8</td>
#> <td style='text-align: right;'>19.7</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>10.4</td>
#> <td style='text-align: right;'>15.0</td>
#> </tr>
#> <tr>
#> <td style='text-align: left;'> Max</td>
#> <td style='text-align: right;'>21.5</td>
#> <td style='text-align: right;'>33.9</td>
#> <td style='text-align: right;'>30.4</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>21.4</td>
#> <td style='text-align: right;'>21.0</td>
#> <td style='text-align: right;'>19.7</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>19.2</td>
#> <td style='text-align: right;'>15.8</td>
#> </tr>
#> <tr><td colspan='11' style='font-weight: 900;'>qsec</td></tr>
#> <tr>
#> <td style='text-align: left;'> Mean</td>
#> <td style='text-align: right;'>20.0</td>
#> <td style='text-align: right;'>19.6</td>
#> <td style='text-align: right;'>16.8</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>19.8</td>
#> <td style='text-align: right;'>17.7</td>
#> <td style='text-align: right;'>15.5</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>17.1</td>
#> <td style='text-align: right;'>14.6</td>
#> </tr>
#> <tr>
#> <td style='text-align: left;'> Min</td>
#> <td style='text-align: right;'>20.0</td>
#> <td style='text-align: right;'>18.5</td>
#> <td style='text-align: right;'>16.7</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>19.4</td>
#> <td style='text-align: right;'>16.5</td>
#> <td style='text-align: right;'>15.5</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>15.4</td>
#> <td style='text-align: right;'>14.5</td>
#> </tr>
#> <tr>
#> <td style='text-align: left;'> Max</td>
#> <td style='text-align: right;'>20.0</td>
#> <td style='text-align: right;'>22.9</td>
#> <td style='text-align: right;'>16.9</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>20.2</td>
#> <td style='text-align: right;'>18.9</td>
#> <td style='text-align: right;'>15.5</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>18.0</td>
#> <td style='text-align: right;'>14.6</td>
#> </tr>
#> <tr><td colspan='11' style='font-weight: 900;'>wt</td></tr>
#> <tr>
#> <td style='text-align: left;'> Mean</td>
#> <td style='text-align: right;'>2.50</td>
#> <td style='text-align: right;'>2.40</td>
#> <td style='text-align: right;'>1.80</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>3.30</td>
#> <td style='text-align: right;'>3.10</td>
#> <td style='text-align: right;'>2.80</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>4.10</td>
#> <td style='text-align: right;'>3.40</td>
#> </tr>
#> <tr>
#> <td style='text-align: left;'> Min</td>
#> <td style='text-align: right;'>2.50</td>
#> <td style='text-align: right;'>1.60</td>
#> <td style='text-align: right;'>1.50</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>3.20</td>
#> <td style='text-align: right;'>2.60</td>
#> <td style='text-align: right;'>2.80</td>
#> <td style='text-align: right;' colspan=1> </td>
#> <td style='text-align: right;'>3.40</td>
#> <td style='text-align: right;'>3.20</td>
#> </tr>
#> <tr>
#> <td style='border-bottom: 2px solid grey; text-align: left;'> Max</td>
#> <td style='border-bottom: 2px solid grey; text-align: right;'>2.50</td>
#> <td style='border-bottom: 2px solid grey; text-align: right;'>3.20</td>
#> <td style='border-bottom: 2px solid grey; text-align: right;'>2.10</td>
#> <td style='border-bottom: 2px solid grey; text-align: right;' colspan=1> </td>
#> <td style='border-bottom: 2px solid grey; text-align: right;'>3.50</td>
#> <td style='border-bottom: 2px solid grey; text-align: right;'>3.40</td>
#> <td style='border-bottom: 2px solid grey; text-align: right;'>2.80</td>
#> <td style='border-bottom: 2px solid grey; text-align: right;' colspan=1> </td>
#> <td style='border-bottom: 2px solid grey; text-align: right;'>5.40</td>
#> <td style='border-bottom: 2px solid grey; text-align: right;'>3.60</td>
#> </tr>
#> </tbody>
#> </table>