根据 ggplotly 图表上的点击事件对数据框进行子集化

Subset a dataframe based on click event on ggplotly chart

我有下面这个闪亮的应用程序,我在其中显示 dfggplotly() 条形图,以及 df2 和数据 table。这 2 个数据帧有一列包含相同的信息 (dose)。我希望能够单击一个栏并自动将 table 中显示的 df2 子集化为相应的数据。例如,如果我按 D1 栏,只有 D1 数据会显示在 table.

library(shiny)
library(ggplot2)
library(plotly)
library(DT)
ui <- fluidPage(
  plotlyOutput("plt"),
  DTOutput("dt")
)
server <- function(input, output) {
  df <- data.frame(dose=c("D0.5", "D1", "D2"),
                   len=c(4.2, 10, 29.5))
  output$plt<-renderPlotly({
    # Basic barplot
    p<-ggplot(data=df, aes(x=dose, y=len)) +
      geom_bar(stat="identity")
    ggplotly(p)
  })
  df2 <- data.frame(dose=c("D0.5", "D1", "D2"),
                   siz=c(2, 10, 2.5))
  output$dt<-renderDT(
    df2
  )
}
shinyApp(ui, server)

只要你的数据集不是很大,看看crosstalkhere。它专为绘图、地图和表格之间的交互而设计。

自动子集化

library(shiny)
library(ggplot2)
library(plotly)
library(DT)
library(crosstalk)

ui <- fluidPage(
  plotlyOutput("plt"),
  DT::dataTableOutput("dt")
)

server <- function(input, output) {
  df <- data.frame(dose=c("D0.5", "D1", "D2"),
                   len=c(4.2, 10, 29.5))
  df2 <- data.frame(dose=c("D0.5", "D1", "D2"),
                    siz=c(2, 10, 2.5))
  
  shared_df <- SharedData$new(df, key = ~dose, group = "group")
  shared_df2 <- SharedData$new(df2, key = ~dose, group = "group")
  
  output$plt<-renderPlotly({
    # Basic barplot
    p <- ggplot(data=shared_df, aes(x=dose, y=len)) +
      geom_bar(stat="identity")
    ggplotly(p)
  })
  
  output$dt<-DT::renderDataTable({
    shared_df2
    }, server = FALSE)
}
shinyApp(ui, server)

手动子集 df2

library(shiny)
library(ggplot2)
library(plotly)
library(DT)
library(crosstalk)

ui <- fluidPage(
  plotlyOutput("plt"),
  DT::dataTableOutput("dt")
)

server <- function(input, output) {
  df <- data.frame(dose=c("D0.5", "D1", "D2"),
                   len=c(4.2, 10, 29.5),
                   stringsAsFactors = F) 
  df2 <- data.frame(dose=c("D0.5", "D1", "D2"),
                    siz=c(2, 10, 2.5),
                    stringsAsFactors = F)
  
  shared_df <- SharedData$new(df, key = ~dose, group = "group")

  output$plt<-renderPlotly({
    # Basic barplot
    p <- ggplot(data=shared_df, aes(x=dose, y=len)) +
      geom_bar(stat="identity")
    ggplotly(p)
  })
  
  dose_filter <- reactive({
         log <- shared_df$selection()
         if(!is.null(log)) {
           log <- shared_df$key()[log]
         } else {
           log <- shared_df$key()
         }
  })
  
   output$dt<- DT::renderDataTable({
    subset(df2, dose %in% dose_filter())
  }, server = FALSE)
  
}
shinyApp(ui, server)