You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从经crosstalk::filter_select过滤的SharedData对象中获取列?

问题

无法通过crosstalk::filter_select筛选SharedData对象后提取到筛选后的列,代码能运行但不响应筛选操作,怀疑shared_data$data(withFilter = TRUE)返回的是原始数据框而非筛选后的版本,如何获取筛选后的数据集?

附上的代码:

---
title: "Dull dashboard"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
---

```{r echo=FALSE, message=FALSE, warning=FALSE}
library(plotly)
library(crosstalk)
library(knitr)
library(tidyverse)

make_plot <- function(tbbl, label){
  ggplot(tbbl, aes(wt, mpg, label=label))+
    geom_text()
}

nested <- mtcars |>
  group_by(cyl) |>
  nest() |>
  mutate(plot=map2(data, cyl, make_plot)) |>
  select(-data)

shared_data <- SharedData$new(nested)

Inputs {.sidebar data-width=250}

crosstalk::filter_select(
  "fltr", 
  " Select # of cylinders",
  shared_data, 
  ~cyl, 
  multiple = FALSE,
  selected = "6"
)

Column {data-width=700}

Plot

filtered_data <- shared_data$data(withFilter = TRUE)
plt <- filtered_data$plot[[1]]
ggplotly(plt)
## 原因分析
`crosstalk`的筛选是**客户端(浏览器端)**的交互操作,而`shared_data$data(withFilter = TRUE)`是在**R页面渲染阶段(服务器端)**执行的,此时还没有用户的筛选操作,因此始终返回原始数据框,无法响应后续的客户端筛选。

## 解决方案
要让图表响应`crosstalk`的筛选,需要让可视化组件直接绑定`SharedData`,而非在R中提取筛选后的数据。以下是两种可行方案:

### 方案1:直接用SharedData驱动plotly图表(推荐)
取消预先生成嵌套plot的逻辑,让plotly直接基于`SharedData`绘制,筛选操作会自动触发客户端图表更新:
```r
---
title: "Dull dashboard"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
---

```{r echo=FALSE, message=FALSE, warning=FALSE}
library(plotly)
library(crosstalk)
library(knitr)
library(tidyverse)

# 基于原始mtcars创建SharedData,指定cyl为关联键
shared_data <- SharedData$new(mtcars, key = ~cyl)

Inputs {.sidebar data-width=250}

crosstalk::filter_select(
  "fltr", 
  "Select # of cylinders",
  shared_data, 
  ~cyl, 
  multiple = FALSE,
  selected = 6
)

Column {data-width=700}

Plot

# 直接用SharedData绘制图表,自动响应筛选
ggplot(shared_data, aes(wt, mpg, label = cyl)) +
  geom_text() |>
  ggplotly()
### 方案2:结合Shiny反应式逻辑(保留预生成plot的需求)
如果需要保留预先按cyl分组生成plot的逻辑,可以将flexdashboard切换为Shiny运行时,用Shiny的反应式机制响应筛选:
```r
---
title: "Dull dashboard"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
    runtime: shiny # 启用Shiny运行时
---

```{r echo=FALSE, message=FALSE, warning=FALSE}
library(plotly)
library(crosstalk)
library(knitr)
library(tidyverse)

make_plot <- function(tbbl, label){
  ggplot(tbbl, aes(wt, mpg, label=label))+
    geom_text()
}

nested <- mtcars |>
  group_by(cyl) |>
  nest() |>
  mutate(plot=map2(data, cyl, make_plot)) |>
  select(-data)

Inputs {.sidebar data-width=250}

# 用Shiny的selectInput替代crosstalk的filter_select
selectInput("fltr", "Select # of cylinders",
            choices = unique(nested$cyl),
            selected = 6)

Column {data-width=700}

Plot

# 用renderPlotly创建反应式图表
renderPlotly({
  filtered_data <- nested |> filter(cyl == input$fltr)
  plt <- filtered_data$plot[[1]]
  ggplotly(plt)
})
---
内容的提问来源于stack exchange,提问作者Richard Martin
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 14:50:02