用串扰过滤两个表 [英] Filter two tables with crosstalk

查看:12
本文介绍了用串扰过滤两个表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am creating a Flexdashboard in R. I want the dashboard to contains both a table and a series of visualizations, that would be filtered through inputs.

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

As I need to deliver a dashboard locally (without a server running in the background), I am unable to use Shiny, hence I rely on crosstalk.

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

I know that the crosstalk package provides limited functionality in the front-end. For instance, the documentation says that you can't aggregate the SharedData object.

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

Nonetheless, I am not clear if I can use the same inputs to filter two different dataframes.

例如,假设我有:

  1. 数据框一:包含原始数据

  1. Dataframe One: Contains original data

df1 <- 结构(列表(所有者 = 结构(c(1L,2L,2L,2L,2L),.Label = c(约翰","Mark"), class = "factor"), hp = c(250, 120, 250, 100, 110),汽车 = 结构(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")

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")

Datafrane 二:包含聚合数据

Datafrane Two: Contains aggregated data

df2 <- 结构(列表(汽车 = 结构(c(1L,2L,1L,2L),.Label = c(奔驰",

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")

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

These two dataframes contain columns with identical values - car and owner. As well as, additional columns too.

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

I could create two different objects:

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)

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

However, that would mean that the user will need to fill inputs that are essentially identical, twice. Also, if the table is large, this would double the size of the memory needed to use the dashboard.

是否可以解决串扰中的这个问题?

Is it possible to work around this problem in crosstalk?

推荐答案

啊,我最近也遇到了这个,SharedData$new(..., group = ) 还有另一个参数!群体论点似乎可以解决问题.当我有两个数据框并使用 group = 时,我偶然发现.

Ah I recently ran into this too, there is another argument to SharedData$new(..., group = )! The group argument seems to do the trick. I found out by accident when I had two dataframes and used the group =.

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

If you make a sharedData object, it will include

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

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

What I think happens is that crosstalk filters the sharedData by the key - for all sharedData objects in the same group! So as long as two dataframes use the same key, you should be able to filter them together in one group.

这应该适用于您的示例.

This should work for your example.

---
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() 中提取数据,但没有运气,直到我找到答案.这就是为什么有一些非常简单的情节与情节.

I spent some time on this by trying to extract data from plot_ly() using plotly_data() without luck until I figured out the answer. That's why there's some very simple plots with plotly.

这篇关于用串扰过滤两个表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆