R:当 tidyverse 动词不起作用时,串扰 :: SharedData 链接数据具有不同的格式(宽/长)

Cla*_*eri 5 r plotly dt tidyverse crosstalk

编辑TL;DR 使用crosstalk包,我正在寻找一种方法来链接利用长格式数据(线图)的图形与宽格式数据的交互式表格,以便表格中的每一行对应于图中的一条线。

我正在尝试将 DT 表与绘图图链接起来。我的麻烦在于图形需要长格式的数据,而表格需要宽格式。我可能专注于 tidyverse 的做事方式。我将尝试提供一个最小的示例,说明我正在尝试做什么以及我想获得什么。

设置:

library(tidyverse)
library(crosstalk)
library(plotly)
library(DT)

# Wide format
df_test1 <- data.frame(
  id = c("id1", "id2"),
  item1 = c(0, 4),
  item2 = c(3, 2),
  item3 = c(1, 4),
  item4 = c(3, 4),
  item5 = c(1, NA)
)

# Reshaped to long format
df_test2 <- 
  df_test1 %>%
  tidyr::pivot_longer(cols = item1:item5, names_to = "item", values_to = "value") %>%
  dplyr::mutate(item = as.factor(item)) %>%
  dplyr::mutate(value = factor(as.character(value), levels = c("0", "1", "2", "3", "4")))
Run Code Online (Sandbox Code Playgroud)

我试过的:

sd1 <- SharedData$new(df_test1, key = ~id)

bscols(
  ggplotly(
    sd1$origData() %>%    # should be sd1, but returns error
      # reshaping
      tidyr::pivot_longer(cols = item1:item5, names_to = "item", values_to = "value") %>%
      dplyr::mutate(item = as.factor(item)) %>%
      dplyr::mutate(value = factor(as.character(value), levels = c("0", "1", "2", "3", "4"))) %>%
      # ploting
      ggplot(., aes(x = value, y = item, group = id)) + 
      geom_path() + 
      geom_point(aes(color = value), size = 3) + 
      scale_x_discrete(position = "top", limits = c("0", "1", "2", "3", "4")), 
  tooltip = c("x", "y", "group"), height = 600, width = 300),     
  datatable(sd1)
)  
Run Code Online (Sandbox Code Playgroud)

当然,这只是因为我使用sd1$origData()而不是sd1串扰功能所需的输出。使用sd1会引发错误,因为 tidyverse 动词不适用于 R6 串扰对象。无论如何,这提供了所需的图形和表格输出,但没有串扰功能。

我希望得到的:

sd2 <- SharedData$new(df_test2, key = ~id)

bscols(
  ggplotly(
    # ploting
    ggplot(sd2, aes(x = value, y = item, group = id)) + 
    geom_path() + 
    geom_point(aes(color = value), size = 3) + 
    scale_x_discrete(position = "top", limits = c("0", "1", "2", "3", "4")),     
  tooltip = c("x", "y", "group"), height = 600, width = 300),    
  datatable(sd2)
) 
Run Code Online (Sandbox Code Playgroud)

这适用于我想要的串扰功能的最小示例,但我需要数据DT::datatable为宽格式。在示例中,点和路径(标记和轨迹)需要链接到id,对于宽格式的每一行,它应该是唯一的。另外,我希望找到一个解决方案,在用户单击所需的表格行之前,所有点和路径都将不可见。
我猜我在这方面走错了路,可能需要做一些我没有想到的事情。我现在读到,在 2021 年,plotly API 可以使用广泛的数据 格式,但还没有找到任何示例说明如何在 R 中实现这一点。

任何帮助将不胜感激。

Leo*_*son 2

诀窍是创建两个 对象,一个是宽格式,一个是长格式,并通过在 的参数SharedData中为这两个对象指定相同的组名称来连接它们。见下文。groupSharedData$new()

library(dplyr)
library(tidyr)
library(crosstalk)
library(plotly)
library(DT)

# Wide format
df_test1 <- data.frame(
  id = c("id1", "id2"),
  item1 = c(0, 4),
  item2 = c(3, 2),
  item3 = c(1, 4),
  item4 = c(3, 4),
  item5 = c(1, NA)
)

# Reshaped to long format
df_test2 <- 
  df_test1 %>%
  tidyr::pivot_longer(cols = item1:item5, names_to = "item", values_to = "value") %>%
  dplyr::mutate(item = as.factor(item)) %>%
  dplyr::mutate(value = factor(as.character(value), levels = c("0", "1", "2", "3", "4")))

# two shared data objects. Note the group argument. 
# this argument can be any string, as long as it is the same in both 
# datasets:
sd1 <- SharedData$new(df_test1, key = ~id, group = "groupdata")
sd2 <- SharedData$new(df_test2, key = ~id, group = "groupdata")

bscols(
  ggplotly(
      ggplot(sd2, aes(x = value, y = item, group = id)) + 
      geom_path() + 
      geom_point(aes(color = value), size = 3) + 
      scale_x_discrete(position = "top", limits = c("0", "1", "2", "3", "4")), 
    tooltip = c("x", "y", "group"), height = 600, width = 300),     
  datatable(sd1)
)  
Run Code Online (Sandbox Code Playgroud)