我有一个数据表(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>