问题描述
我正在 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.
例如,假设我有:
数据框一:包含原始数据
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屋!
更多推荐
[db:关键词]
发布评论