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