DT icon indicating copy to clipboard operation
DT copied to clipboard

A lot of digits in shiny DT

Open ly0ka opened this issue 2 years ago • 8 comments

After upgrading to R version 4.3.1 and DT 0.28, in shiny DT tables sometimes have a lot of digits, but in the dataframe the number is rounded - round(x / 0.01) * 0.01 It is not suitable to set a common number of digits for all row. Each row has a unique rounding step 0.1, 0.01, 0.001...

image

ui <- fluidPage(
  actionButton(inputId = "update", label = "Update"),
  DTOutput("tbl")
)

server <- function(input, output) {
  dt_tbl <- eventReactive(
    eventExpr = input$update,
    ignoreNULL = FALSE,
    valueExpr = data.table(price = round(runif(n = 10, min = 0.8, max = 0.85) / 0.01) * 0.01))
  
  output$tbl <- renderDT(isolate(expr = {
    datatable(dt_tbl(),
              class = "cell-border stripe", extensions = "FixedHeader", selection = "none", rownames = FALSE,
              options = list(dom = "t", fixedHeader = TRUE, paging = FALSE, ordering = FALSE,
                             columnDefs = list(list(className = "dt-center", targets = "_all"))))
  }))
  
  observe(dataTableProxy("tbl") %>% replaceData(dt_tbl(), rownames = FALSE))
  
}

shinyApp(ui, server)

Stack Overflow


By filing an issue to this repo, I promise that

  • [x] I have fully read the issue guide at https://yihui.org/issue/.
  • [x] I have provided the necessary information about my issue.
  • [x] I have learned the Github Markdown syntax, and formatted my issue correctly.

ly0ka avatar Jun 22 '23 16:06 ly0ka

Hello,

That's normal. The way you use to round the numbers is not correct:

> x = round(runif(n = 10, min = 0.8, max = 0.85) / 0.01) * 0.01
> print(x, digits = 16)
 [1] 0.8300000000000001 0.8200000000000001 0.8400000000000000 0.8400000000000000
 [5] 0.8300000000000001 0.8000000000000000 0.8000000000000000 0.8400000000000000
 [9] 0.8200000000000001 0.8400000000000000

stla avatar Jun 23 '23 07:06 stla

But in the version R 4.2.3, the table did not show these digits

ly0ka avatar Jun 23 '23 07:06 ly0ka

Strange. I tried other ways but the problem occurs as well:

x = round(runif(n = 10, min = 0.8, max = 0.85), 2) 
print(x, digits = 16)

x = round(runif(n = 10, min = 0.8, max = 0.85) * 100) / 100 
print(x, digits = 16)

You should use formatRound?

stla avatar Jun 23 '23 08:06 stla

No, each row has a unique round value fromatRound rounds all over the column

ly0ka avatar Jun 23 '23 09:06 ly0ka

Hmm that's annoying. Maybe you should use JavaScript then, the option rowCallback.

stla avatar Jun 23 '23 09:06 stla

In fact the easiest way is to get the rounded numbers as character strings and then to use the column-wise option render to transform them to numbers when you sort a column (if you don't use the sorting, no need of render).

stla avatar Jun 28 '23 11:06 stla

Agree, I came to this conclusion and use as.character for all numeric columns before render DT

ly0ka avatar Jun 28 '23 14:06 ly0ka

The problem with as.character is that you will not get what is expected when sorting a column. Unless you use the render option.

stla avatar Sep 06 '23 13:09 stla