过滤两个有串扰的表

Posted

技术标签:

【中文标题】过滤两个有串扰的表【英文标题】:Filter two tables with crosstalk 【发布时间】:2018-07-12 21:22:38 【问题描述】:

我正在 R 中创建一个 Flexdashboard。我希望仪表板同时包含一个表格和一系列可视化,这些可视化将通过输入进行过滤。

由于我需要在本地交付仪表板(没有在后台运行服务器),我无法使用 Shiny,因此我依赖于串扰。

我知道 crosstalk 包在前端提供的功能有限。例如,文档说您不能聚合 SharedData 对象。

不过,我不清楚是否可以使用相同的输入来过滤两个不同的数据帧

例如,假设我有:

    数据框一:包含原始数据

    df1

    Datafrane 二:包含聚合数据

    df2

    “宝马”),class=“因素”),所有者=结构(c(1L,1L,2L,2L ), .Label = c("John", "Mark"), class= "factor"), freq = c(0L, 1L, 2L, 2L)), .Names = c("car", "owner", "freq"), row.names = c(NA, -4L), class= "data.frame")

这两个数据框包含具有相同值的列 - car 和 owner。此外,还有其他列。

我可以创建两个不同的对象:

library(crosstalk)
shared_df1 <- SharedData$new(df1)
shared_df2 <- SharedData$new(df2)

比:

filter_select("owner", "Car owner:", shared_df1, ~ owner)
filter_select("owner", "Car owner:", shared_df2, ~ owner)

但是,这意味着用户将需要两次填写基本相同的输入。此外,如果表很大,这将使使用仪表板所需的内存大小增加一倍。

是否有可能在串扰中解决这个问题?

【问题讨论】:

据我了解 Crosstalk,它允许从单个数据帧(共享数据)创建过滤器。为了使它在两个数据帧上工作,一个将被要求使用 joins 只创建一个 shareddata 。但是,我很想知道其他方式来做到这一点。 【参考方案1】:

啊我最近也遇到了这个,SharedData$new(..., group = )还有一个说法!群体论点似乎起到了作用。当我有两个数据框并使用group =时,我偶然发现了。

如果你创建一个 sharedData 对象,它将包含

一个数据框 选择行的键 - 最好是唯一的,但不一定。 组名

我认为发生的是串扰通过键过滤 sharedData - 对于同一组中的所有 sharedData 对象!因此,只要两个数据帧使用相同的键,您就应该能够将它们一起过滤到一组中。

这应该适用于您的示例。

---
title: "blabla"
output:
   flexdashboard::flex_dashboard:
   orientation: rows
   social: menu
   source_code: embed
   theme: cerulean
---

```r
library(plotly)
library(crosstalk)
library(tidyverse)
```

```r Make dataset
df1 <- structure(list(owner = structure(c(1L, 2L, 2L, 2L, 2L), .Label = c("John", "Mark"), class = "factor"), hp = c(250, 120, 250, 100, 110), car = structure(c(2L, 2L, 2L, 1L, 1L), .Label = c("benz", "bmw"), class = "factor"), id = structure(1:5, .Label = c("car1", "car2", "car3", "car4", "car5"), class = "factor")), .Names = c("owner", "hp", "car", "id"), row.names = c(NA, -5L), class = "data.frame")

df2 <- structure(list(car = structure(c(1L, 2L, 1L, 2L), .Label = c("benz", 
"bmw"), class = "factor"), owner = structure(c(1L, 1L, 2L, 2L
), .Label = c("John", "Mark"), class = "factor"), freq = c(0L, 
1L, 2L, 2L)), .Names = c("car", "owner", "freq"), row.names = c(NA, 
-4L), class = "data.frame")
```

#

##

### Filters

```r
library(crosstalk)
# Notice the 'group = ' argument - this does the trick!
shared_df1 <- SharedData$new(df1, ~owner, group = "Choose owner")
shared_df2 <- SharedData$new(df2, ~owner, group = "Choose owner")

filter_select("owner", "Car owner:", shared_df1, ~owner)
# You don't need this second filter now
# filter_select("owner", "Car owner:", shared_df2, ~ owner)
```

### Plot1 with plotly

```r
plot_ly(shared_df1, x = ~id, y = ~hp, color = ~owner) %>% add_markers() %>% highlight("plotly_click")
```

### Plots with plotly

```r
plot_ly(shared_df2, x = ~owner, y = ~freq, color = ~car) %>% group_by(owner) %>% add_bars()
```

##

### Dataframe 1

```r
DT::datatable(shared_df1)
```

### Dataframe 2

```r
DT::datatable(shared_df2)
```

我花了一些时间尝试使用plotly_data()plot_ly() 中提取数据,但没有找到答案。这就是为什么有一些非常简单的情节与情节。

【讨论】:

这太棒了。感谢您的帮助! 很好的答案!如果你有时间可以看看我的问题吗? ***.com/questions/66699881/interactive-plots-in-r谢谢【参考方案2】:

最近,我还想使用一个过滤器来过滤 2 个可视化。

简要说明我的情况 我想使用一个过滤器来过滤箱线图和表格。 源数据一直是一个数据框。我想为箱线图使用一些变量并计算一些统计数据(如平均值、标准差、模式、记录数)。 我需要用来显示结果的函数:plotly::plot_ly()、DT::datatable()、crosstalk::bscols()。

我发现有3个关键信息来解决这种情况关键1)必须正确创建共享数据。 就我而言,我不得不使用 crosstalk::SharedData$new() 两次。 如果首先满足键 2 和 3,则可以使用正确的共享数据,用作可视化的源。 关键 2) 创建共享数据时,使用与 2018 年 3 月 16 日解释的“Lodewic Van Twillert”相同的组参数。关键 3) 确保所有 SharedData 实例在概念上都引用相同的数据点,并共享相同的键。 首先确保数据框具有行名称,即使行名称是带有数字的字符向量(如“1”、“2”、...)。 此键 3 的使用文献:https://rstudio.github.io/crosstalk/using.html。 (我建议主要阅读副标题“分组”。)

步骤摘要我已经用来满足上述关键信息关键3)为了满足关键3的相关条件,这可能会很棘手更多。 我选择的方法创建了一个包含所有数据的表,该表(数据框)将用于创建两个共享数据。 我已经对原始数据框(risk_scores_df)应用了数据操作,所以现在这个数据有一个新列。 我创建了一个带有统计信息的新数据框。 我已经使用加入了两个数据框 risk_scores_df &lt;- dplyr::left_join... 所以现在原始数据框包含所有准备好的数据。 我已经运行print(rownames(risk_scores_df)) 以确保我更新的数据框具有行名。 现在,我有一个数据框,其中包含满足上述关键 3 信息条件的所有数据(两种可视化都需要)。 Key 2) 我只是在两个 crosstalk::SharedData$new() 中添加了 group = "sd1" Key 1) 这个也可能很棘手如果选择了错误的方法。 在这里,创建正确共享数据实例的关键是使用一个包含所有数据的表,并仅选择相关共享数据所需的行和列。 示例 - 就我而言,我在选项 1 中运行代码来创建两个共享数据实例,但选项 2 也是可能的。

选项 1(在 crosstalk::SharedData$new() 中只选择需要的行和列)

  rs_df_sd1 <- crosstalk::SharedData$new(
    risk_scores_df[, c(1, 2, 5)],
    group = "sd1"
  )
  rs_df_sd1a <- crosstalk::SharedData$new(
    risk_scores_df[risk_scores_df$NumRecords > 0 &
                   is.na(risk_scores_df$NumRecords) == F,
                   c(1, 6:11)],
    group = "sd1"
  )

选项 2(仅在附加变量中选择需要的行和列)

  sd1 <- risk_scores_df[, c(1, 2, 5)]
  sd1a <- risk_scores_df[risk_scores_df$NumRecords > 0 &
                         is.na(risk_scores_df$NumRecords) == F,
                         c(1, 6:11)]

  rs_df_sd1 <- crosstalk::SharedData$new(sd1, group = "sd1")
  rs_df_sd1a <- crosstalk::SharedData$new(sd1a, group = "sd1")

完成解决方案 至此,我创建了共享数据实例 rs_df_sd1 和 rs_df_sd1a,它们可用作可视化的主要来源,将使用 crosstalk::bscols() 进行过滤。 简单例子:

  box_n_jitter_chart1 <- plotly::plot_ly(rs_df_sd1) %>% add_trace(...
  DT_table1 <- DT::datatable(rs_df_sd1a)
  crosstalk::bscols(
    widths = c(6, 12, NA),
    crosstalk::filter_select(
      id = "idAvgRisk",
      label = "Account",
      sharedData = rs_df_sd1,
      group = ~Account,
      multiple = F
    ),
    box_n_jitter_chart1,
    DT_table1
  )

注意:DT::datatable() 也可以使用rs_df_sd1a$data()cells = list(values = base::rbind(...(请参阅使用cells = ...;查看有关使用cells 的更多信息,例如https://plotly.com/r/reference/table/)但是因为使用了method data() (请参阅 https://rdrr.io/cran/crosstalk/man/SharedData.html#method-data 的更多信息)然后它不适用于 crosstalk::bscols。

【讨论】:

以上是关于过滤两个有串扰的表的主要内容,如果未能解决你的问题,请参考以下文章

如何减少万兆以太网线外部串扰

如何减少万兆以太网线外部串扰

如何减少万兆以太网线外部串扰

闪亮的两个情节和串扰问题

plotly 串扰过滤器过滤错误,从变量中泄漏其他类别的值

高速SERDES信号走线上的AC耦合电容应该放在哪个位置?