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

Posted

技术标签:

【中文标题】根据ggplotly图表上的点击事件对数据框进行子集【英文标题】:Subset a dataframe based on click event on ggplotly chart 【发布时间】:2021-06-03 02:30:48 【问题描述】:

我在下面有一个闪亮的应用程序,我在其中显示dfggplotly() 条形图和df2 和一个数据表。这两个数据框有一列具有相同的信息 (dose)。我希望能够单击一个栏并自动将表格中显示的df2 子集到相应的数据中。例如,如果我按D1 栏,表格中只会显示D1 数据。

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)

【问题讨论】:

【参考方案1】:

只要您的数据集不是很大,请查看crosstalk 包here。它专为绘图、地图和表格之间的交互而设计。

自动子集

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)

【讨论】:

确实是很好的答案。你能看看这个串扰吗? ***.com/questions/66508869/… 一张表可以连接多张图表吗? 关于您以后的问题(4 个数据集 - 3 个图和 1 个表)以及您的目标是只有表而不是图应该做出反应,我认为 flexdashboard 中的串扰无法做到这一点闪亮的。你可能需要一个反应函数来过滤你的表数据集,就像上面的第二个例子一样。比 3 个绘图数据集中的每一个都需要转换为一个 sharedDataframe(每个都有自己的组参数,键可能是绘图的 x 轴变量)。而且,您可以使用反应函数中的三个 sharedDataframe 过滤表数据集。 谢谢你能检查一下 whis 没有按预期工作吗? ***.com/questions/66537874/…

以上是关于根据ggplotly图表上的点击事件对数据框进行子集的主要内容,如果未能解决你的问题,请参考以下文章

echarts区域统计取消选框事件

数据框结构防止条形图显示在 ggplotly() 图表中

echarts 取消图例上的点击事件和图表上鼠标滑过点击事件

根据ggplot中的两个条件对条形图进行排序

React js从父事件中更新子状态

数据可视化 | 使用R语言绘制专业图表(Ⅰ)——ggplot2 图形语法基础