davidgohel / flextable

table farming
https://ardata-fr.github.io/flextable-book/
554 stars 79 forks source link

Allow `colformat_double()` (and other numeric functions) to round with `signif()` or similar? #572

Closed ian-curtis closed 6 months ago

ian-curtis commented 1 year ago

Introduction

I am in the process of writing a package for a specific audience (introductory statistics students). I am working with professors to help students focus on the statistical concepts and not the code for plots and tables. My package creates curated plots and charts designed for this purpose (and tailored to my university's program) and I use the flextable package for my tables due to the variety of output formats supported.

It's a fantastic package and I appreciate the time spent on it. The documentation is VERY well written and I have been able to find everything I need until now.

My Request

It is very possible that my request is something that can already be done. If so, I apologize and hope someone is able to lead me in the correct direction.

I currently have all my functions rounding to 3 "actual" digits (which the user can change). However, the faculty would like this rounding to be 3 (or n) non-zero digits after the decimal point (so 0.00000004567 rounded to 3 digits would not be 0.000, but 0.0000000457 and 2.000003456 would be 2.0000346) to meet their pedagogical needs when teaching statistics.

Is this possible to build into the colformat_double() function (and related numerical ones)? Perhaps I need to just create a function myself to do this but I figured I'd get your take on this first. It seems more complicated than just using signif().

Note: I checked out a StackOverflow post but this answer didn't work for me.

I appreciate your time and any help you can give!

ian-curtis commented 12 months ago

Apologies for another comment. After further discussions with the faculty, we have decided to only round using significant digits for values between -1 and 1. I have created a custom function for this and do the rounding before calling flextable::flextable(). I do have to convert them into a character otherwise colformat_double() takes control but this issue is not as pressing nor as complicated.

However, I do still wonder if significant digit rounding could be implemented? Otherwise, how might I use colformat_double() for some of its features while ignoring others (e.g., I use it for na_str but don't need it for digits currently.

Thanks for listening to my rambling and for a great package!

davidgohel commented 11 months ago

Sorry for the silence! We are busy and can not spend time on this for now but will come back to this thread later, hopefully not too late :)

davidgohel commented 11 months ago

Does that code help?

library(flextable)
set_flextable_defaults(na_str = "Not available")
ft <- flextable(head(airquality))
fff <- function(z) {
  x <- sprintf("%04.0f", z)
  x[is.na(z)] <- NA_character_
  x
}
ft <- set_formatter(ft, Ozone = fff)
# ft <- set_formatter(ft, values = list(Ozone = fff)) # probably better in a package
ft
ian-curtis commented 7 months ago

Apologies for a late response here! This works great! I ended up making some modifications to my own function but the structure here was what I needed. Thank you very much!

davidgohel commented 6 months ago

I've added a function that does what you described. It also handle NA (that can be defined via set_flextable_defaults(na_str = "N/A"))

x <- data.frame(
  x = c(0.00000004567, 2.000003456, 3, pi)
)
ft_1 <- flextable(x)
ft_1 <- align(x = ft_1, j = 1, align = "left")
mk_par(ft_1, value = as_paragraph(
  fmt_signif_after_zeros(x)))
Capture d’écran 2024-02-29 à 22 32 36
github-actions[bot] commented 3 weeks ago

This old thread has been automatically locked. If you think you have found something related to this, please open a new issue and link to this old issue if necessary.