benjaminrich / table1

79 stars 26 forks source link

The digits.pct argument for rounding does nothing #43

Closed cole-johanson closed 3 years ago

cole-johanson commented 3 years ago
library(table1)
#> 
#> Attaching package: 'table1'
#> The following objects are masked from 'package:base':
#> 
#>     units, units<-
df = data.frame(x=c(1,2,2))
table1(~x,df,digits.pct=2)
#> [1] "<table class=\"Rtable1\">\n<thead>\n<tr>\n<th class='rowlabel firstrow lastrow'></th>\n<th class='firstrow lastrow'><span class='stratlabel'>Overall<br><span class='stratn'>(N=3)</span></span></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td class='rowlabel firstrow'><span class='varlabel'>x</span></td>\n<td class='firstrow'></td>\n</tr>\n<tr>\n<td class='rowlabel'>Mean (SD)</td>\n<td>1.67 (0.577)</td>\n</tr>\n<tr>\n<td class='rowlabel lastrow'>Median [Min, Max]</td>\n<td class='lastrow'>2.00 [1.00, 2.00]</td>\n</tr>\n</tbody>\n</table>\n"
table1(~x,df,digits.pct=3)
#> [1] "<table class=\"Rtable1\">\n<thead>\n<tr>\n<th class='rowlabel firstrow lastrow'></th>\n<th class='firstrow lastrow'><span class='stratlabel'>Overall<br><span class='stratn'>(N=3)</span></span></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td class='rowlabel firstrow'><span class='varlabel'>x</span></td>\n<td class='firstrow'></td>\n</tr>\n<tr>\n<td class='rowlabel'>Mean (SD)</td>\n<td>1.67 (0.577)</td>\n</tr>\n<tr>\n<td class='rowlabel lastrow'>Median [Min, Max]</td>\n<td class='lastrow'>2.00 [1.00, 2.00]</td>\n</tr>\n</tbody>\n</table>\n"

You can see the mean 1.67 does not change to 1.667 when digits.pct=3. I suggest updating the stats.apply.rounding function to accept digits = NULL, which will trigger the use of digits.pct instead. Something like:

r <- NULL
if(!is.null(digits)) {
  r <- lapply(x, signif_pad, digits = digits, round.integers = round.integers, round5up = round5up)
} else {
  r <- lapply(x, round_pad, digits = digits.pct, round5up = round5up)
}
benjaminrich commented 3 years ago

I think you did not understand the purpose of digits.pct (maybe the documentation wasn't very clear). In table1, rounding is handled different for "ordinary" numeric values like means, and for percentages (i.e. for categorical variables, or %missing values), by default (obviously everything is customizable, but this is the default behavior). The digits.pct option applies specifically to the latter (i.e. percentages), while the digits option applies in the more general case. I modified you example by adding a categorical variable to demonstrate:

library(table1)
df = data.frame(x=c(1,2,2), y=c("A", "A", "B"))
table1(~ x + y , data=df, digits.pct=5)

image

As you can see, the percentages have 5 decimal places, while other numeric values have 3 significant digits.

cole-johanson commented 3 years ago

Thank you. Re-reading without looking for functionality that does not exist, I see the documentation is actually quite clear:

An integer specifying the number of digits after the decimal place for percentages.

I will open a separate feature request.