在模块内并且更改选择标准后,如何在Shiny中更新DT数据表

时间:2019-03-24 22:34:32

标签: r shiny dt

我尝试制作一个闪亮的模块,以使用DT包显示数据帧中的数据。我想使用一个模块来设置DT表选项的标准设置,例如语言和其他选项。

我希望用户能够交互地选择数据的不同子集,然后再将数据视为DT表。子集的选择将在模块外部生成,因为我希望该子集可用于其他用途,例如导出到csv文件。

当我不使用用于制作DT表的模块时,此方法按预期工作。当我将代码放入模块中时,在应用启动时会生成一个表。但是当选择标准更改时,表不会更新。

我提供了一个说明问题的应用。表1是在不使用闪亮模块的情况下生成的,并且在选择更改时按预期更新。表2是使用该模块输出的,更改选择后不会更新。

我正在运行R-studio 1.1.463,R版本3.5.2和DT版本0.5。

require("DT")
require("shiny")

# module for presenting data using DT
showDTdataUI <- function(id) { 
  ns <- NS(id)
  tagList(
    DT::dataTableOutput(ns("table"))
  )
  }

showDTdata <- function(input, output, session, DTdata) {
  output$table <- renderDataTable({
      DT::datatable(DTdata)
    })
}

# User interface
ui <- 
  fluidPage(
    sidebarLayout(
      sidebarPanel(id="DT",
                   width = 4,
                   helpText(h4("Select")),
                   selectInput("selectedSpecies", label = "Species",
                               choices = c("setosa","versicolor","virginica"), 
                               selected = "versicolor")
      ),
      mainPanel(
        h3("Table 1. Presenting selected data from Iris" ),
        DT::dataTableOutput("table"),
        h5(br("")),
        h3("Table 2. Presenting selected data from Iris using shiny module"),
        showDTdataUI(id="testDTModule")
      )
    )
  )


# Define server logic ----
server <- function(session, input, output) {

  selectedIris <- reactive ( {
    selected <- iris[which(iris$Species==input$selectedSpecies),]
    selected
  })

  output$table <- renderDataTable({
    DT::datatable(selectedIris())
  })

  callModule(showDTdata, id="testDTModule", DTdata=selectedIris())

}

# Run the app ----
shinyApp(ui = ui, server = server)

3 个答案:

答案 0 :(得分:1)

您必须通过showDTdata中的无功导体:

showDTdata <- function(input, output, session, DTdata) {
  output$table <- renderDataTable({
    DT::datatable(DTdata()) # not datatable(DTdata)
  })
}

callModule(showDTdata, id="testDTModule", DTdata=selectedIris) # not DTdata=selectedIris()

答案 1 :(得分:0)

这是您想要的吗?我删除了您的函数,并将selection ='multiple'添加到表1(tableX)中,以便我们随后可以收听tableX_rows_selected

P.S .:我已经注意到,如果您先加载DT,然后再进行闪亮处理,则整个应用将无法再使用。这有点怪异,因为我们使用DT :: ...调用了所有数据表函数,但是,您会收到一条警告消息,提示DT的某些部分被闪亮或反之掩盖。

require("shiny")
require('DT')


# User interface
ui <- 
    fluidPage(
        sidebarLayout(
            sidebarPanel(id="DT",
                         width = 4,
                         helpText(h4("Select")),
                         selectInput("selectedSpecies", label = "Species",
                                     choices = c("setosa","versicolor","virginica"), 
                                     selected = "versicolor")
            ),
            mainPanel(
                h3("Table 1. Presenting selected data from Iris" ),
                DT::dataTableOutput("tablex"),
                br(),
                h3("Table 2. Presenting selected data from Iris using shiny module"),
                DT::dataTableOutput("table2")

            )
        )
    )


# Define server logic ----
server <- function(session, input, output) {

    values <- reactiveValues(rowselect = numeric())

    selectedIris <- reactive ( {
        selected <- iris[which(iris$Species==input$selectedSpecies),]
        selected
    })

    output$tablex <- renderDataTable({
        DT::datatable(selectedIris(), selection = 'multiple')
    })


    IrisSelected <- reactive({ 
        df <- iris[c(input$tablex_rows_selected), ]
        df
    })


    output$table2 <- renderDataTable({
        req(nrow(IrisSelected()) > 0)
        DT::datatable( IrisSelected())
    })  
}

# Run the app ----
shinyApp(ui = ui, server = server)

答案 2 :(得分:0)

如果不了解闪亮的模块方法,我可能会像正常函数一样编写它。下面的应用程序可以工作,但是在看到@Stephane的答案后,我现在很好奇,相比于常规函数方法,使用callModule方法有什么优势

require("DT")
require("shiny")


makeTable <- function(dataframe) { DT::datatable(dataframe) %>% 
                                   formatStyle(names(dataframe), background = '#fff') 
                                  }

# User interface
ui <- 
  fluidPage(
    sidebarLayout(
      sidebarPanel(id="DT",
                   width = 4,
                   helpText(h4("Select")),
                   selectInput("selectedSpecies", label = "Species",
                               choices = c("setosa","versicolor","virginica"), 
                               selected = "versicolor")
      ),
      mainPanel(
dataTableOutput('Table1')
      )
    )
  )


# Define server logic ----
server <- function(session, input, output) {

  selectedIris <- reactive ( {
    selected <- iris[which(iris$Species==input$selectedSpecies),]
    selected
  })

 output$Table1 <- renderDataTable(makeTable(selectedIris()))
}

# Run the app ----
shinyApp(ui = ui, server = server)