闪亮模块内的可编辑 DT
editable DT inside shiny module
我想在闪亮的模块中有一个 editable DT。当我更改 DT 中的值时,table 更新并且它是空的,数据中的消息 table:
"No matching records found"
我的代码如下:
模块:
modDtUi <- function(id){ # UI module
ns = NS(id)
DT::dataTableOutput(ns('x1'))
}
modDt <- function(input, output, session, data){ # Server module
x <- data
output$x1 <- DT::renderDataTable(x, selection = 'none', editable = TRUE)
proxy <- dataTableProxy('x1', session = session)
observeEvent(input$x1_cell_edit, {
info = input$x1_cell_edit
str(info)
print(info)
i = info$row
j = info$col
v = info$value
x[i, j] <<- DT::coerceValue(v, x[i, j])
replaceData(proxy, x, resetPaging = FALSE, rownames = FALSE)
})
}
flexdashboard 中的应用程序:
```{r}
modDtUi("editable")
```
```{r}
callModule(modDt,"editable", data = iris)
```
它在没有模块的情况下工作得很好,但我无法通过闪亮的模块获得相同的结果。
谢谢
以下为我提供了一个 editable table 并在反应中捕获编辑后的 table 以便在应用程序中进一步使用:
library(shiny)
library(DT)
modDtUi <- function(id){ # UI module
ns = NS(id)
DT::dataTableOutput(ns('x1'))
}
modDt <- function(input, output, session, data){ # Server module
output$x1 <- DT::renderDataTable(data, selection = 'none', editable = TRUE, server = TRUE)
proxy <- dataTableProxy('x1', session = session)
updatedData <- eventReactive(input$x1_cell_edit, {
info = input$x1_cell_edit
if (!is.null(info)) {
str(info)
data[info$row, info$col] <<- DT::coerceValue(info$value,
data[info$row, info$col])
}
data
}, ignoreNULL = FALSE)
return(updatedData)
}
ui <- fluidPage(
modDtUi("editable"),
tags$hr(),
"Proof it works: the table below updates on edit.",
shiny::tableOutput("proof")
)
server <- function(input, output) {
editable_dt <- callModule(modDt,"editable", data = iris)
output$proof <- renderTable({
editable_dt() %>%
summarise_if(is.numeric, mean)
})
}
shinyApp(ui = ui, server = server)
如果您删除 rownames = FALSE
:
,这会起作用
replaceData(proxy, x, resetPaging = FALSE)#, rownames = FALSE)
如果您不需要行名称,您还必须在 renderDataTable
:
中设置 rownames = FALSE
output$x1 <- DT::renderDataTable(x, selection = 'none', editable = TRUE,
rownames = FALSE)
然后你必须添加 1
到 info$col
:
observeEvent(input$x1_cell_edit, {
info = input$x1_cell_edit
i = info$row
j = info$col + 1
v = info$value
x[i, j] <<- DT::coerceValue(v, x[i, j])
replaceData(proxy, x, resetPaging = FALSE, rownames = FALSE)
})
Rmd
flexdashboard 的完整代码:
---
title: "Untitled"
output:
flexdashboard::flex_dashboard:
orientation: columns
vertical_layout: fill
runtime: shiny
---
```{r setup, include=FALSE}
library(flexdashboard)
library(DT)
modDtUi <- function(id){ # UI module
ns = NS(id)
DT::dataTableOutput(ns('x1'))
}
modDt <- function(input, output, session, data){ # Server module
x <- data
output$x1 <- DT::renderDataTable(x, selection = 'none', editable = TRUE,
rownames = FALSE)
proxy <- dataTableProxy('x1', session = session)
observeEvent(input$x1_cell_edit, {
info = input$x1_cell_edit
i = info$row
j = info$col + 1
v = info$value
x[i, j] <<- DT::coerceValue(v, x[i, j])
replaceData(proxy, x, resetPaging = FALSE, rownames = FALSE)
})
}
```
Column {data-width=650}
-----------------------------------------------------------------------
### Editable table
```{r}
modDtUi("editable")
```
```{r}
callModule(modDt, "editable", data = iris)
```
根据您的代码,问题是代理需要全局会话(而不是模块会话)。请参阅我的其他答案以了解替代方法。
您可以简单地将全局 session
通过参数传递给模块。
这个有效:
library(shiny)
library(DT)
modDtUi <- function(id){ # UI module
ns = NS(id)
DT::dataTableOutput(ns('x1'))
}
modDt <- function(input, output, session, data, globalSession){ # Server module
x <- data
output$x1 <- DT::renderDataTable(x, selection = 'none', editable = TRUE)
proxy <- dataTableProxy('x1', session = globalSession)
observeEvent(input$x1_cell_edit, {
info = input$x1_cell_edit
str(info)
print(info)
i = info$row
j = info$col
v = info$value
x[i, j] <<- DT::coerceValue(v, x[i, j])
replaceData(proxy, x, resetPaging = FALSE)
})
}
您现在必须在模块调用中添加全局会话。
有了闪亮的应用程序:
ui <- fluidPage(
modDtUi("editable")
)
server <- function(input, output, session) {
callModule(modDt,"editable", data = iris, globalSession = session)
}
shinyApp(ui = ui, server = server)
使用 flexdashboard:
```{r}
modDtUi("editable")
```
```{r}
callModule(modDt, "editable", data = iris, globalSession = session)
```
如果您想在应用程序的其余部分使用更新后的 table,只需从模块中 return reactive(x)
并在调用模块时捕获它。
editable_iris <- callModule(modDt,"editable", data = iris, globalSession = session)
我想在闪亮的模块中有一个 editable DT。当我更改 DT 中的值时,table 更新并且它是空的,数据中的消息 table:
"No matching records found"
我的代码如下:
模块:
modDtUi <- function(id){ # UI module
ns = NS(id)
DT::dataTableOutput(ns('x1'))
}
modDt <- function(input, output, session, data){ # Server module
x <- data
output$x1 <- DT::renderDataTable(x, selection = 'none', editable = TRUE)
proxy <- dataTableProxy('x1', session = session)
observeEvent(input$x1_cell_edit, {
info = input$x1_cell_edit
str(info)
print(info)
i = info$row
j = info$col
v = info$value
x[i, j] <<- DT::coerceValue(v, x[i, j])
replaceData(proxy, x, resetPaging = FALSE, rownames = FALSE)
})
}
flexdashboard 中的应用程序:
```{r}
modDtUi("editable")
```
```{r}
callModule(modDt,"editable", data = iris)
```
它在没有模块的情况下工作得很好,但我无法通过闪亮的模块获得相同的结果。
谢谢
以下为我提供了一个 editable table 并在反应中捕获编辑后的 table 以便在应用程序中进一步使用:
library(shiny)
library(DT)
modDtUi <- function(id){ # UI module
ns = NS(id)
DT::dataTableOutput(ns('x1'))
}
modDt <- function(input, output, session, data){ # Server module
output$x1 <- DT::renderDataTable(data, selection = 'none', editable = TRUE, server = TRUE)
proxy <- dataTableProxy('x1', session = session)
updatedData <- eventReactive(input$x1_cell_edit, {
info = input$x1_cell_edit
if (!is.null(info)) {
str(info)
data[info$row, info$col] <<- DT::coerceValue(info$value,
data[info$row, info$col])
}
data
}, ignoreNULL = FALSE)
return(updatedData)
}
ui <- fluidPage(
modDtUi("editable"),
tags$hr(),
"Proof it works: the table below updates on edit.",
shiny::tableOutput("proof")
)
server <- function(input, output) {
editable_dt <- callModule(modDt,"editable", data = iris)
output$proof <- renderTable({
editable_dt() %>%
summarise_if(is.numeric, mean)
})
}
shinyApp(ui = ui, server = server)
如果您删除 rownames = FALSE
:
replaceData(proxy, x, resetPaging = FALSE)#, rownames = FALSE)
如果您不需要行名称,您还必须在 renderDataTable
:
rownames = FALSE
output$x1 <- DT::renderDataTable(x, selection = 'none', editable = TRUE,
rownames = FALSE)
然后你必须添加 1
到 info$col
:
observeEvent(input$x1_cell_edit, {
info = input$x1_cell_edit
i = info$row
j = info$col + 1
v = info$value
x[i, j] <<- DT::coerceValue(v, x[i, j])
replaceData(proxy, x, resetPaging = FALSE, rownames = FALSE)
})
Rmd
flexdashboard 的完整代码:
---
title: "Untitled"
output:
flexdashboard::flex_dashboard:
orientation: columns
vertical_layout: fill
runtime: shiny
---
```{r setup, include=FALSE}
library(flexdashboard)
library(DT)
modDtUi <- function(id){ # UI module
ns = NS(id)
DT::dataTableOutput(ns('x1'))
}
modDt <- function(input, output, session, data){ # Server module
x <- data
output$x1 <- DT::renderDataTable(x, selection = 'none', editable = TRUE,
rownames = FALSE)
proxy <- dataTableProxy('x1', session = session)
observeEvent(input$x1_cell_edit, {
info = input$x1_cell_edit
i = info$row
j = info$col + 1
v = info$value
x[i, j] <<- DT::coerceValue(v, x[i, j])
replaceData(proxy, x, resetPaging = FALSE, rownames = FALSE)
})
}
```
Column {data-width=650}
-----------------------------------------------------------------------
### Editable table
```{r}
modDtUi("editable")
```
```{r}
callModule(modDt, "editable", data = iris)
```
根据您的代码,问题是代理需要全局会话(而不是模块会话)。请参阅我的其他答案以了解替代方法。
您可以简单地将全局 session
通过参数传递给模块。
这个有效:
library(shiny)
library(DT)
modDtUi <- function(id){ # UI module
ns = NS(id)
DT::dataTableOutput(ns('x1'))
}
modDt <- function(input, output, session, data, globalSession){ # Server module
x <- data
output$x1 <- DT::renderDataTable(x, selection = 'none', editable = TRUE)
proxy <- dataTableProxy('x1', session = globalSession)
observeEvent(input$x1_cell_edit, {
info = input$x1_cell_edit
str(info)
print(info)
i = info$row
j = info$col
v = info$value
x[i, j] <<- DT::coerceValue(v, x[i, j])
replaceData(proxy, x, resetPaging = FALSE)
})
}
您现在必须在模块调用中添加全局会话。
有了闪亮的应用程序:
ui <- fluidPage(
modDtUi("editable")
)
server <- function(input, output, session) {
callModule(modDt,"editable", data = iris, globalSession = session)
}
shinyApp(ui = ui, server = server)
使用 flexdashboard:
```{r}
modDtUi("editable")
```
```{r}
callModule(modDt, "editable", data = iris, globalSession = session)
```
如果您想在应用程序的其余部分使用更新后的 table,只需从模块中 return reactive(x)
并在调用模块时捕获它。
editable_iris <- callModule(modDt,"editable", data = iris, globalSession = session)