【发布时间】:2022-01-17 12:10:34
【问题描述】:
我正在尝试使用反应值在模块之间共享数据,使用this 想法,但是当它尝试传递更新的数据时,闪亮会抛出错误,rv$data 不是数据框,而是我认为的反应对象.详细地,数据表在汇总表中进行汇总,并绘制出来。编辑数据表时,我希望汇总表和绘图也更新。
library(shiny)
library(DT)
library(tidyverse)
#summary modules----
summary_ui <- function(id){
ns <- NS(id)
DT::dataTableOutput(ns("summary_table"))
}
summary_server <- function(id,data){
shiny::moduleServer(
id,
function(input, output, session) {
output$summary_table <- DT::renderDataTable({
sum_data <- data %>%
group_by(Brand) %>%
summarise_all(list(sum))
DT::datatable(sum_data, editable = TRUE)
})
})
}
#data table modules----
data_ui <- function(id) {
ns <- NS(id)
DT::dataTableOutput(ns("data_table"))
}
data_server <- function(input, output, session, data,reset) {
print(isolate(colnames(data)))
output$data_table <- DT::renderDataTable({
DT::datatable(data, editable = TRUE)
})
}
#edit datatable----
edit_server <- function(input, output, session, data) {
ns <- session$ns
proxy = dataTableProxy("data_table")
observeEvent(input$data_table_cell_edit, {
print(names(data))
info = input$data_table_cell_edit
str(info)
i = info$row
j = info$col
k = info$value
str(info)
isolate(
if (j %in% match(c("ratio","cost","updated_price"), names(data))) {
print(match(c("ratio","cost", "updated_price"), names(data)))
data[i, j] <<- DT::coerceValue(k, data[i, j])
print(data)
if (j %in% match("cost", names(data))) {
data$updated_price <<- data$cost * data$ratio
}
if (j %in% match("ratio", names(data))) {
data$updated_price <<- data$cost * data$ratio
}
} else {
stop("You are not supposed to change this column.") # check to stop the user from editing only few columns
}
)
replaceData(proxy, data, resetPaging = FALSE) # replaces data displayed by the updated table
})
result <- reactiveValues(
data=NULL,
trigger=NULL
)
result$data <- data
result$trigger <- 1
return(result)
}
#plot modules----
plot_ui <- function(id){
ns <- NS(id)
plotOutput(ns(id))
}
plot_server <- function(id,data){
moduleServer(
id,
function(input,output,session){
output$price_plot <- renderPlot({
ns <- NS(id)
data %>%
ggplot()+
aes(x=cost,y=updated_price)+
geom_point()
})
})
}
#dataset-----------------------
input_data <- data.frame(Brand = c("Brand1", "Brand2","Brand3","Brand1", "Brand2","Brand3","Brand1", "Brand2","Brand3"),
ratio = rep(0.5,9),
cost = seq(from=100,to=1000,length.out=9)) %>%
mutate(updated_price = cost * ratio)
#ui----------------------------------------
ui = fluidPage(
fluidRow(
column(6,data_ui(id="data_table")),
column(6,plot_ui(id="price_plot"))
),
fluidRow(
column(6,summary_ui(id="summary_table"))
),
)
#server-----------------------------------------
server = function(input, output, session) {
rv <- reactiveValues(data = input_data,trigger=NULL)
observe({ rv$data <- input_data })
#data table----------------------
callModule(data_server,"data_table", data=rv$data)
#edit table----
data_mod <- callModule(module = edit_server, id = "mod",data = reactive(rv$data))
observeEvent(data_mod$trigger,{
#error: rv reactiveValue not being updated correctly
rv$data <- data_mod$data
})
#summary table----
summary_server("summary_table",data=rv$data)
#plot----
plot_server(id="price_plot",data=rv$data)
}
#app-----
shinyApp(ui = ui, server = server)
【问题讨论】:
-
在所有模块中,除了函数参数在哪里,不应该代替
data、data()?例如:sum_data <- data() %>%而不是sum_data <- data %>%? -
还有
observeEvent(data_mod$trigger,{ rv$data <- data_mod })不应该是observeEvent(data_mod()$trigger,{ rv$data <- data_mod })?我也不明白$trigger来自哪里,所以我不确定这是否正确。 -
@gss 数据是一个数据框而不是一个函数,所以
data()是不正确的,我从附加的链接中得到了data_mod$trigger方法 -
这可能没有什么不同,但您的
ui和server分配没有使用正确的“callModule(data_server,"data_table", data=rv$data) 应该是callModule(data_server,"data_table", data=reactive(rv$data))吗? -
感谢您的建议,但没有成功