Я создал приложение в блестящем содержании, связь между модулями которого не работает должным образом. Краткое описание моего приложения: Мое приложение имеет два selectInputs. Он обновляет второй selectInput в зависимости от первого selectInput, а затем строит график и таблицу для данных df. Я хочу, чтобы в моем приложении было три модуля: модуль выбора данных, модуль таблицы и модуль графика. Я создал эти модули, но кажется, что разные модули не взаимодействуют друг с другом. SelectInputs работают хорошо, но график и таблица не строятся. Я создал минимальный пример этого. Я очень ценю любую помощь, которую каждый может предоставить.
library(shiny)
library(plotly)
library(reshape2)
#----------------------------------------------------------------------------------------
# Dataselect module
dataselect_ui<- function(id) {
ns<-NS(id)
tagList(
selectInput(ns("Nametype"),"Select a name type",
choices=c("Name1","Name2","choose"),selected = "choose"),
selectInput(ns("Name"),"Select a name",
choices = "",selected = "",selectize=TRUE)
)
}
dataselect_server <- function(id) {
moduleServer(id, function(input, output, session) {
# Data preparation
df<-data.frame(Name1<-c("Aix galericulata","Grus grus"," Alces alces"),
Name2<-c("Mandarin Duck","Common Crane" ,"Elk"),
eventDate<-c("2015-03-11","2015-03-10","2015-03-10"),
individualCount<-c(1, 10, 1)
)
colnames(df)<-c("Name1","Name2","eventDate","individualCount")
# Putting columns Name1 and Nam2 of df in one column called nameType using melt()function
# This format of data is needed for the choices argument of updateSelectizeInput()
df2<-reshape2::melt(df,id=c("eventDate","individualCount"))
colnames(df2)<-c("eventDate","individualCount","nameType","Name")
observeEvent(
input$Nametype,
updateSelectizeInput(session, "Name", "Select a name",
choices = unique(df2$Name[df2$nameType==input$Nametype]),selected = ""))
# finalDf() is the data used to plot the table and plot
finalDf<-reactive({
if (input$Name= = "choose"){
return(NULL)
}
if (input$Name= = ""){
return(NULL)
}
if (input$Nametype= = "choose"){
return(NULL)
}
# if the first selectInput is set to Name1, from df select rows their Name1 column are
# equal to the second selectInput value
else if (input$Nametype= = "Name1"){
finalDf<-df[which(df$Name1==input$Name) ,]
}
# if the first selectInput is set to Name2, from df select rows their Name2 column are
# equal to the second selectInput value
else if (input$Nametype= = "Name2"){
finalDf<-df[which(df$Name2==input$Name) ,]
}
return(finalDf)
})
return(
list("finalDf" = finalDf, "input_Name" = reactive(input$Name))
)
})
}
#-------------------------------------------------------------------------------------
# Table module
table_ui <- function(id) {
ns<-NS(id)
tagList(
DT::DTOutput(ns("tab"))
)
}
table_server <- function(id) {
moduleServer(id, function(input, output, session) {
module_outputs <- dataselect_server("dataselect")
input_Name <- module_outputs$input_Name
finalDf <- module_outputs$finalDf
output$tab<-DT::renderDT({
req(input_Name())
datatable(finalDf(), filter = 'top',
options = list(pageLength = 5, autoWidth = TRUE),
rownames= FALSE)
})
})
}
#--------------------------------------------------------------------------------------
# Plot module
plot_ui <- function(id) {
ns<-NS(id)
tagList(
plotlyOutput(ns("plot"))
)
}
plot_server <- function(id) {
moduleServer(id, function(input, output, session) {
module_outputs <- dataselect_server("dataselect")
input_Name <- module_outputs$input_Name
finalDf <- module_outputs$finalDf
output$plot <- renderPlotly({
req(input_Name())
p<-ggplot(finalDf(),aes(x=eventDate,y=individualCount)) +geom_point(alpha=0.2, shape=21, color = "black",fill = "red",size=5)+
labs( x = "Date Event",y= "Individual Count") +theme_bw()
p<-ggplotly(p)
p
})
})
}
#--------------------------------------------------------------------------------------
# application
ui <- fluidPage(
dataselect_ui("dataselect"),
table_ui("table1"),
plot_ui("plot1")
)
server <- function(session,input, output) {
dataselect_server("dataselect")
table_server("table1")
plot_server("plot1")
}
shinyApp(ui = ui, server = server)
Я не знаю, что было не так в вашем коде. Я изменил смысл приложения: вместо того, чтобы вызывать модуль dataselect
в двух других модулях, я вызываю его только в основном server
и передаю его выходные данные в качестве аргументов двух других модулей.
Сюжет появляется, но не уверен, что приложение делает то, что вы ожидаете, скажите, пожалуйста.
library(shiny)
library(plotly)
library(reshape2)
library(DT)
#----------------------------------------------------------------------------------------
# Dataselect module ####
dataselect_ui <- function(id) {
ns <- NS(id)
tagList(
selectInput(ns("Nametype"), "Select a name type",
choices = c("Name1", "Name2", "choose"), selected = "choose"
),
selectInput(ns("Name"), "Select a name",
choices = "", selected = "", selectize = TRUE
)
)
}
dataselect_server <- function(id) {
moduleServer(id, function(input, output, session) {
# Data preparation
df <- data.frame(
Name1 = c("Aix galericulata", "Grus grus", " Alces alces"),
Name2 = c("Mandarin Duck", "Common Crane", "Elk"),
eventDate = c("2015-03-11", "2015-03-10", "2015-03-10"),
individualCount = c(1, 10, 1)
)
colnames(df) <- c("Name1", "Name2", "eventDate", "individualCount")
# Putting columns Name1 and Nam2 of df in one column called nameType using melt()function
# This format of data is needed for the choices argument of updateSelectizeInput()
df2 <- reshape2::melt(df, id = c("eventDate", "individualCount"))
colnames(df2) <- c("eventDate", "individualCount", "nameType", "Name")
observeEvent(
input$Nametype,
updateSelectizeInput(session, "Name", "Select a name",
choices = unique(df2$Name[df2$nameType == input$Nametype]), selected = ""
)
)
# finalDf() is the data used to plot the table and plot
finalDf <- reactive({
if (input$Name == "choose") {
return(NULL)
}
if (input$Name == "") {
return(NULL)
}
if (input$Nametype == "choose") {
return(NULL)
}
# if the first selectInput is set to Name1, from df select rows their Name1 column are
# equal to the second selectInput value
if (input$Nametype == "Name1") {
finalDf <- df[which(df$Name1 == input$Name), ]
}
# if the first selectInput is set to Name2, from df select rows their Name2 column are
# equal to the second selectInput value
else if (input$Nametype == "Name2") {
finalDf <- df[which(df$Name2 == input$Name), ]
}
return(finalDf)
})
return(
list("finalDf" = finalDf, "input_Name" = reactive(input$Name))
)
})
}
#-------------------------------------------------------------------------------------
# Table module ####
table_ui <- function(id) {
ns <- NS(id)
tagList(
DTOutput(ns("tab"))
)
}
table_server <- function(id, input_Name, finalDf) {
moduleServer(id, function(input, output, session) {
output$tab <- renderDT({
req(input_Name())
datatable(finalDf(),
filter = "top",
options = list(pageLength = 5, autoWidth = TRUE),
rownames = FALSE
)
})
})
}
#--------------------------------------------------------------------------------------
# Plot module ####
plot_ui <- function(id) {
ns <- NS(id)
tagList(
plotlyOutput(ns("plot"))
)
}
plot_server <- function(id, input_Name, finalDf) {
moduleServer(id, function(input, output, session) {
output$plot <- renderPlotly({
req(input_Name())
p <- ggplot(finalDf(), aes(x = eventDate, y = individualCount)) +
geom_point(alpha = 0.2, shape = 21, color = "black", fill = "red", size = 5) +
labs(x = "Date Event", y = "Individual Count") +
theme_bw()
p <- ggplotly(p)
p
})
})
}
#--------------------------------------------------------------------------------------
# application ####
ui <- fluidPage(
dataselect_ui("dataselect"),
table_ui("table1"),
plot_ui("plot1")
)
server <- function(session, input, output) {
x <- dataselect_server("dataselect")
input_Name <- x$input_Name
finalDf <- x$finalDf
table_server("table1", input_Name, finalDf)
plot_server("plot1", input_Name, finalDf)
}
shinyApp(ui = ui, server = server)
.Да, это работает, и приложение делает то, что я ожидаю. Большое спасибо. @Стефан Лоран