**R – G-Forge**, and kindly contributed to R-bloggers)

One of the most pleasant surprises has been the popularity of my **htmlTable**-package with more than 100k downloads per month. This is all thanks to more popular packages relying on it and the web expanding beyond its original boundaries. As a thank you I have taken the time to update and fix some features (the 1.13 release) – enjoy!

## Grouping column headers

Grouping columns is a powerful feature that allows you to quickly generate more interesting tables. Unfortunately the `cgroup`

has previously required matrix input for this feature that even I as the author sometimes struggled with. Now you can provide a `list`

in a much more user friendly manner:

rbind( `Group A` = c(20, 5, 380, 95), `Group B` = c(11, 55, 9, 45) ) %>% htmlTable(header = rep(c("No", "%"), times = 2), n.cgroup=list( c(2), c(2,2)), cgroup=list('Super', c("First", "Second")))

Super | |||||
---|---|---|---|---|---|

First | Second | ||||

No | % | No | % | ||

Group A | 20 | 5 | 380 | 95 | |

Group B | 11 | 55 | 9 | 45 |

The `n.cgroup`

can be either a combination of the `cgroup`

below but the exact same table can be created through providing `list(c(4),c(2,2))`

as the `n.cgroup`

.

## Auto-counting tspanners

Even more common than grouping columns is probably grouping data by rows. The htmlTable allows you to do this by `rgroup`

and `tspanner`

. The most common approach is by using `rgroup`

as the first row-grouping element but with larger tables you frequently want to separate concepts into separate sections. Here’s a more complex example. This has previously been a little cumbersome to to counting the rows of each tspanner but now you’re able to (1) leave out the last row, (2) specify the number of rgroups instead of the number of rows. The latter is convenient as the `n.tspanner`

must align with the underlying rgroup. Here’s an example:

rbind( `Group A` = c(20, 380), `Group B` = c(110, 1230), `Group C` = c(2, 56), `Group D` = c(17, 33), `Group A` = c(40, 360), `Group B` = c(230, 1100), `Group C` = c(8, 50), `Group D` = c(10, 40) ) %>% apply(1, function(x) { sapply(x, function(count) c( txtInt(count), sprintf("(%s)", txtRound(count/sum(x) * 100, 1)))) %>% c(txtInt(sum(x)), .) }) %>% t %>% htmlTable(header = c("Total", rep(c("No", "(%)"), times = 2)), n.cgroup=list(c(1,2,2)), cgroup=list(c("", "Cases", "Controls")), rgroup = rep(c("Aspirin", "Intermittent compression"), times = 2), n.rgroup = rep(2, times = 4), tspanner = c("First experiment", "Second experiment"), n.tspanner = c(2), align = "r", caption = "Extremely fake data")

Extremely fake data | |||||||

Cases | Controls | ||||||
---|---|---|---|---|---|---|---|

Total | No | (%) | No | (%) | |||

First experiment | |||||||

Aspirin | |||||||

Group A | 400 | 20 | (5.0) | 380 | (95.0) | ||

Group B | 1,340 | 110 | (8.2) | 1,230 | (91.8) | ||

Intermittent compression | |||||||

Group C | 58 | 2 | (3.4) | 56 | (96.6) | ||

Group D | 50 | 17 | (34.0) | 33 | (66.0) | ||

Second experiment | |||||||

Aspirin | |||||||

Group A | 400 | 40 | (10.0) | 360 | (90.0) | ||

Group B | 1,330 | 230 | (17.3) | 1,100 | (82.7) | ||

Intermittent compression | |||||||

Group C | 58 | 8 | (13.8) | 50 | (86.2) | ||

Group D | 50 | 10 | (20.0) | 40 | (80.0) |

## The txtRound now has `digits.nonzero`

argument

The **txtRound** is similar to R’s `round`

but returns a string that makes sure that all your values are presented with the same number of digits.

> txtRound(c(1.2, 1.0), digits = 1) [1] "1.2" "1.0"

Under some circumstances you are close to 0 and you want to retain more digits, hence the new

`digits.nonzero`

argument:

> txtRound(c(0.1, 0.01, 0.001), digits = 1, digits.nonzero = 2) [1] "0.1" "0.01" "0.0"

## New function **vector2string**

As a package author I think the majority of my code is dedicated towards providing good error message. A common issue is that you have two vectors that don’t match. For this purpose I’ve created the **vector2string**. This makes it easier to write your `stop`

messages. You simply provide any vector and get a string back:

> vector2string(c(1:2, "a random ' string")) [1] "'1', '2', 'a random \\' string'"

Here’s how I use is in one of my functions:

... stop("Invalid size of lists: ", vector2string(lengths), " each element should be be able to evenly divide ", ncol(x))

## Summary

These are tiny additions and everything should work just as it has in previous versions. Hopefully it will save you some time and make *your* life easier! Enjoy!

**leave a comment**for the author, please follow the link and comment on their blog:

**R – G-Forge**.

R-bloggers.com offers

**daily e-mail updates**about R news and tutorials on topics such as: Data science, Big Data, R jobs, visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...