【问题标题】:How to filter one datatable from another on two tabs in shiny如何在闪亮的两个选项卡上从另一个数据表中过滤一个数据表
【发布时间】:2018-09-17 18:48:57
【问题描述】:

我有一个数据集,它是特定类别的汇总数据集。 我有另一个数据集,它提供了每个类别的详细信息(我们从中计算了汇总统计数据)。

我希望能够在选项卡中拥有两个数据集,但我希望能够单击摘要数据集的一行并仅调用该特定类别的数据。

所以,如果我对 iris 数据集的每个物种都有一组汇总均值:

     Species Sepal.Length Sepal.Width Petal.Length Petal.Width n..
1     setosa        5.006       3.428        1.462       0.246  50
2 versicolor        5.936       2.770        4.260       1.326  50
3  virginica        6.588       2.974        5.552       2.026  50

我希望能够单击一条线,然后调用每个物种的数据子集。例如,如果我单击 Setosa 的行,我希望在第二个选项卡中看到以下内容:

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1           5.1         3.5          1.4         0.2  setosa
2           4.9         3.0          1.4         0.2  setosa
3           4.7         3.2          1.3         0.2  setosa
4           4.6         3.1          1.5         0.2  setosa
5           5.0         3.6          1.4         0.2  setosa
...

我已经寻找了一些线索,但没有找到任何有效的方法。

任何帮助将不胜感激。我在下面包含了一个工作闪亮的应用程序:

#### Shiny app test #### 

#### Read in necessary libraries ####

library(shiny)
library(flexdashboard)
library(shinydashboard)
library(shinythemes)
library(DT)
library(dplyr)

#### Necessary functions 

#### create some data ####

data1<-iris %>%
  group_by(Species) %>%
  dplyr::summarize(Sepal.Length=mean(Sepal.Length,na.rm=TRUE),
                   Sepal.Width=mean(Sepal.Width,na.rm=TRUE),
                   Petal.Length=mean(Petal.Length,na.rm=TRUE),
                   Petal.Width=mean(Petal.Width,na.rm=TRUE),
                   n())

data2<-iris

#### UI function ####

ui <- dashboardPage(

 dashboardHeader(title="Shiny Tool"),

 dashboardSidebar(),

 dashboardBody(
        tabsetPanel(

          tabPanel("page1",
                   div(DT::dataTableOutput("page1"), style=c("color:black"))
          ),

          tabPanel("page2",
                   div(DT::dataTableOutput("page2"), style=c("color:black"))
          )
       )

    )
)

#### Server function ####

server <- shinyServer(function(input, output, session) {

    output$page1 = DT::renderDataTable({
      data1
    })

    output$page2 <-  DT::renderDataTable({
        data2
    })

  })

shinyApp(ui = ui, server = server)

更新:

使用下面的@JasonAizkalns 建议,我尝试在 Shiny 中实现这一点,但在第二个选项卡中出现错误(“'data' must be 2-dimensional (e.g. data frame or matrix)”)。

这是我的代码:

#### Shiny app test #### 

#### Read in necessary libraries ####

library(shiny)
library(flexdashboard)
library(shinydashboard)
library(shinythemes)
library(DT)
library(dplyr)

#### Necessary functions 

#### create some data ####

data1<-iris %>%
  group_by(Species) %>%
  dplyr::summarize(Sepal.Length=mean(Sepal.Length,na.rm=TRUE),
                   Sepal.Width=mean(Sepal.Width,na.rm=TRUE),
                   Petal.Length=mean(Petal.Length,na.rm=TRUE),
                   Petal.Width=mean(Petal.Width,na.rm=TRUE),
                   n())

data2<-iris

#### UI function ####

ui <- dashboardPage(

 dashboardHeader(title="Shiny Tool"),

 dashboardSidebar(),

 dashboardBody(
        tabsetPanel(

          tabPanel("page1",
                   div(DT::dataTableOutput("page1"), style=c("color:black"))
          ),

          tabPanel("page2",
                   div(DT::dataTableOutput("page2"), style=c("color:black"))
          )
       )

    )
)

#### Server function ####

server <- shinyServer(function(input, output, session) {

  selected_row   = reactive({validate(need(selected_row > 0, "Please select a row."))
                            input$summary_data_rows_selected})

  selected_species = reactive(data1$Species[selected_row])

  temp = reactive(data2 %>% dplyr::filter(Species==selected_species))

    output$page1 = DT::renderDataTable({
      data1
    }, selection = 'single')


    output$page2 <-  DT::renderDataTable({
        temp
    })

  })

shinyApp(ui = ui, server = server)

【问题讨论】:

    标签: r shiny dt


    【解决方案1】:

    这在html_notebook 中更容易(也更简洁)显示,但概念通常相同。基本上你需要identify which row was selected in the DataTable。您可以通过input$TABLE_ID_data_rows_selected 执行此操作——诚然,这感觉很尴尬。在我的示例中,我的 TABLE_IDsummary_data,因此,我们使用 input$summary_data_rows_selectednot input$summary_data$rows_selected 或类似的东西。

    我们还应该注意一些事情:

    • 在我们的renderDataTable 调用中使用selection = "single" 以确保用户只能单击一行。
    • 我们应该添加一个validate(need()) 语句,以确保用户至少选择了一条记录,如果他们没有选择,请给出友好的消息。

    最后,如果要制作这两个标签,请将Column 行更改为Column {.tabset}

    ---
    title: "Selecting a Row in a DataTable"
    output: flexdashboard::flex_dashboard
    runtime: shiny
    ---
    
    ```{r setup, include=FALSE}
    library(dplyr)
    library(DT)
    ```
    
    Column
    -------------------------------------
    
    ### Summary Table    
    ```{r}    
    dataTableOutput("summary_data")
    
    my_table <- iris %>%
      group_by(Species) %>%
      add_count() %>%
      summarise_all(mean)
    
    output$summary_data <- renderDataTable({
      my_table
    }, selection = 'single')
    ```   
    
    ### Details        
    ```{r}
    renderTable({
      selected_row     <- input$summary_data_rows_selected
      selected_species <- my_table$Species[selected_row]
    
      validate(need(selected_row > 0, "Please select a row."))
    
      iris %>%
        filter(Species == selected_species)
    })
    

    【讨论】:

    • 感谢您的回复。我试图让它在 Shiny 中工作,但遇到了麻烦。我可以给你发消息吗?
    【解决方案2】:

    如果您想在 Jason 的出色回答之外获得进一步的解释,来自 rstudio::conf2018 的演讲 (https://www.rstudio.com/resources/videos/drill-down-reporting-with-shiny/) 和相关代码 (https://github.com/bborgesr/rstudio-conf-2018) 会很有帮助。

    【讨论】:

      猜你喜欢
      • 2018-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-17
      • 1970-01-01
      • 1970-01-01
      • 2019-01-18
      • 2014-10-22
      相关资源
      最近更新 更多