Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

signif() + datatable() bug #1127

Open
le-raman opened this issue Mar 4, 2024 · 3 comments
Open

signif() + datatable() bug #1127

le-raman opened this issue Mar 4, 2024 · 3 comments

Comments

@le-raman
Copy link

le-raman commented Mar 4, 2024

Hi devs,

Reporting following bug, using R v4.3.2 and DT v0.27.

DT::datatable(signif(data.frame(3.234866680561728e-127), 3))

I expected:

image

But got:

image

Any idea what causes this?

@yihui
Copy link
Member

yihui commented Mar 4, 2024

I think this is a problem on htmltools or htmlwidgets's side. The data is correct on DT's side:

> x = DT::datatable(signif(data.frame(3.234866680561728e-127), 3))
> str(x)
List of 8
 $ x            :List of 6
  ..$ filter   : chr "none"
  ..$ vertical : logi FALSE
  ..$ data     :'data.frame':	1 obs. of  2 variables:
  .. ..$                       : chr "1"
  .. ..$ X3.23486668056173e.127: num 3.23e-127
[...]

but 3.23e-127 is converted to 3.229999999999999e-127 when the widget is rendered to HTML:

> str(htmlwidgets:::toHTML(x))
List of 3
 $ :List of 3
  ..$ : NULL
  ..$ :List of 3
  .. ..$ name    : chr "div"
[...]
 $ :List of 3
  ..$ name    : chr "script"
  ..$ attribs :List of 2
  .. ..$ type    : chr "application/json"
  .. ..$ data-for: chr "htmlwidget-6b6194a1b92c04b274c8"
  ..$ children:List of 1
  .. ..$ : 'html' chr "{\"x\":{\"filter\":\"none\",\"vertical\":false,\"data\":[[\"1\"],[3.229999999999999e-127]],\"container\":\"<tab"| __truncated__
  .. .. ..- attr(*, "html")= logi TRUE

@le-raman
Copy link
Author

le-raman commented Mar 4, 2024

I see, thanks for the response. The strange thing, it doesn't happen when directly running DT::datatable(signif(data.frame(3.23e-127), 3)). Anyway, I switched to using %>% DT::formatSignif(... which solves my issue.

@jcheng5
Copy link
Member

jcheng5 commented Mar 20, 2024

Unfortunately I think this is just a natural consequence of floating point imprecision. (I couldn't reproduce DT::datatable(signif(data.frame(3.23e-127), 3)) looking "correct"--on my machine it looked the same as the first case.)

> print(signif(3.23e-127, 3), digits=16)
[1] 3.229999999999999e-127

R defaults to precision of digits=7 when printing, while htmlwidgets defaults to digits=16 when serializing to the browser. The idea in theory is that the value should be transmitted with max precision, but when actually displayed in the web page you can use less precision. Unfortunately I can't think of a single htmlwidget that goes out of its way to display with fewer digits.

I don't know if it's a good idea to do so, but you can use options(shiny.json.digits = xxx) to set the precision to whatever you want. This gets passed to the jsonlite::toJSON() function's digits argument.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants