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

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

问题描述

我正在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<-structure(list(owner = structure(c(1L,2L,2L,2L,2L),.Label = c(约翰,
马克),类=因子),马力= 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),类= 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<-structure(list(car = structure(c(1L,2L,1L,2L),.Label = c( benz,

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)),。名称= c(汽车,所有者,频率),row.names = c(NA,

  • -4L),class = data.frame)
  • "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")

这些两个数据框包含具有相同值的列-汽车和所有者。以及其他列。

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()提取数据>运气不好,直到我找出答案。这就是为什么有一些带有plotly的非常简单的图。

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天全站免登陆