crosstalk x plot_ly sankey?

50 Views Asked by At

I was trying to add a filtering widget from the crosstalk package to a Sankey plot, generated with plot_ly, but I'm not sure how to pass the SharedData object to plot_ly in Sankey mode.

#dummy data
df <- data.frame(id = 1:100)

# randomly assign gender and personality traits
df$gender <- sample(c("Male", "Female"), 100, replace = TRUE)
df$field <- sample(c("Science", "Art", "Business", "Law"), 100, replace = TRUE)

# assign personality traits based on field of study
df$personality <- ifelse(df$field %in% c("Science", "Art"),
                         sample(c("Introverted", "Introverted", 
                                  "Introverted", "Extroverted"), 100, 
                                replace = TRUE),
                         ifelse(df$field == "Business",
                                sample(c("Introverted", "Extroverted", 
                                         "Extroverted"), 100, replace = TRUE),
                                sample(c("Introverted", "Extroverted"),
                                       100, replace = TRUE)))

# use ifelse() to set gender proportions based on field of study
df$gender <- ifelse(df$field %in% c("Science", "Business"),
                    sample(c("Male", "Female"), 100, replace = TRUE,
                           prob = c(0.611, 0.389)),
                    ifelse(df$field == "Art",
                           sample(c("Male", "Female"), 100, 
                                  replace = TRUE, prob = c(0.388, 0.612)),
                           sample(c("Male", "Female"), 100,
                                  replace = TRUE, prob = c(0.545, 0.455))))


freq_table <- df %>% group_by(personality, field, gender) %>% 
  summarise(n = n())

# create a nodes data frame
nodes <- data.frame(name = unique(c(as.character(freq_table$personality),
                                    as.character(freq_table$field),
                                    as.character(freq_table$gender))))
# create links dataframe
links <- data.frame(source = match(freq_table$personality, nodes$name) - 1,
                    target = match(freq_table$field, nodes$name) - 1,
                    value = freq_table$n,
                    stringsAsFactors = FALSE)

links <- rbind(links,
               data.frame(source = match(freq_table$field, nodes$name) - 1,
                          target = match(freq_table$gender, nodes$name) - 1,
                          value = freq_table$n,
                          stringsAsFactors = FALSE))

SharedData object:


# SharedData for the crosstalk between plot_ly and the filtering widget

library(crosstalk)
sankey_nodes <- SharedData$new(data = nodes,
                              key = 'name'
)

Error at the plot_ly level:

library(plot_ly)
# fails here: 

p1 <- plot_ly(
  type = "sankey",
  orientation = "h",
  node = list(pad = 15,
              thickness = 20,
              line = list(color = "black", width = 0.5),
              label = sankey_nodes),
  link = list(source = links$source,
              target = links$target,
              value = links$value),
  textfont = list(size = 10),
  width = 720,
  height = 480
) %>%
  layout(title = "Sankey Diagram: Personality, Field, and Gender",
         font = list(size = 14),
         margin = list(t = 40, l = 10, r = 10, b = 10))

p2 <- p1 %>% 
  filter_checkbox(label = 'name', sharedData = sankey_nodes, group = ~name) 


bscols(
  widths = c(8, 4), p1, 
  p2
)



> Error in unclass(x) : cannot unclass an environment
0

There are 0 best solutions below