如何使用闪亮的/数据表检查已编辑单元格的数字数据类型?

时间:2020-04-27 16:45:02

标签: r shiny dt

我有一个数据表(DT),其中有一列数字数据类型。用户可以编辑此列的单元格,但我想检查其输入的数字是否有效。

我遇到的问题:在任何情况下,input$myDT_cell_edit返回一个字符串,例如“ 25.15”。如果我将as.numeric()转换为数字,则只要输入为不是有效的数字,例如“ 25m15”。 (也许我应该只取消这个警告?)

我尝试了三种不同的解决方案,但是它们都非常复杂。我想知道是否没有更简单的解决方案,这是DT固有的功能,因为检查正确的输入类型是标准问题。也许我可以使用column rendering,但是我缺少必要的JavaScript知识。

我已经解决了问题。但是,由于我是R编程,Shiny和DT的新手,所以我想了解我是否缺少某些东西。

下面是一个最小的示例(REPREX),以显示我尝试过的内容。

``` r
library(shiny)
library(DT)
#> 
#> Attaching package: 'DT'
#> The following objects are masked from 'package:shiny':
#> 
#>     dataTableOutput, renderDataTable
library(tibble)

df <- tibble::as_tibble(c(20:25))

ui <- fluidPage(
        fluidRow(column(1,DT::DTOutput("myDT")))
)

server <- function(input, output, session) {
    data <- reactiveValues(df = df)

    showData <- reactive({
        DT::datatable(
            data$df,
            options = list(
                dom = 't',
                autoWidth = TRUE,
                columnDefs = list(
                    list(width = '75px', targets = c(0,1)),
                    list(type = 'natural', targets = 0)
                )
            ),
            colnames = c('ID' = 1),
            plugins = 'natural',
            editable = list(
                target = "cell", disable = list(columns = 0))
        )

    })

    output$myDT <- DT::renderDT({showData()})

    #####

    ########################################### first version
    # checkValue <-  function(info) {
    #     k = NULL
    #     i = info$row
    #     j = info$col
    #     k =  tryCatch({
    #         as.numeric(info$value)
    #         }, warning = function(war) {
    #             k <<- as.numeric(data$df[i,j][[1]])
    #         }, finally = {
    #             k = as.numeric(k)
    #         })
    #     data$df[i,j][[1]] = k
    #     data$df
    # }

    ########################################## second version
    # checkValue <- function(info) {
    #     v = "[\\!#$%&()*/:;<=>?@_`|~{}ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ]"
    #     i = info$row
    #     j = info$col
    #     k = info$value
    #     if (regexec(v, k) == -1) {
    #         data$df[i,j][[1]] = as.numeric(k)
    #     }
    #     data$df
    # }

    ########################################## third version
    checkValue <- function(info) {
        i = info$row
        j = info$col
        oldValue  <-  data$df[i,j][[1]]
        newValue = suppressWarnings(isolate(DT::coerceValue(info$value, as.double(oldValue))))
        if (!is.na(newValue)) {data$df[i,j][[1]] <- newValue}
        data$df
    }

    observeEvent(input$myDT_cell_edit, {
        showData <- DT::replaceData(
            DT::dataTableProxy("myDT"),
            checkValue(input$myDT_cell_edit),
            resetPaging = FALSE
        )
    })


}

shinyApp(ui, server)
#> 
#> Listening on http://127.0.0.1:4640
```

![](https://i.imgur.com/OKAwOKL.png)

<sup>Created on 2020-04-27 by the [reprex package](https://reprex.tidyverse.org) (v0.3.0)</sup>

0 个答案:

没有答案