Этот отвратительный рекурсивный подход:
require(dplyr)
require(purrr)
x = list(
`believe in aliens` = list(
n = 50,
`believe aliens visit/visited Earth` = list(n = 5),
`believe in aliens elsewhere in universe` = list(n = 45)
),
`do not believe in aliens` = list(n = 50)
)
parse_edge = function(parent_name, lst){
lst_names = names(lst)[names(lst) != 'n']
if(length(lst_names) == 0) return(tibble())
this_edges = map_df(lst_names, ~ tibble(from = parent_name, to = .x, weight = lst[[.x]]$n))
child_edges = map2_df(lst_names, lst[lst_names], ~ parse_edge(.x, .y))
bind_rows(this_edges, child_edges)
}
parse_edge('People who', x)
#> # A tibble: 4 x 3
#> from to weight
#> <chr> <chr> <dbl>
#> 1 People who believe in aliens 50
#> 2 People who do not believe in aliens 50
#> 3 believe in aliens believe aliens visit/visited Earth 5
#> 4 believe in aliens believe in aliens elsewhere in universe 45
df = parse_edge('People who', x)
g = igraph::graph_from_data_frame(df)
# or..
require(networkD3)
n = as.data.frame(enframe(unique(c(df$from, df$to)), name = NULL, value = 'id'))
e = as.data.frame(df) %>% mutate(from = match(from, n$id)-1, to = match(to, n$id)-1)
sankeyNetwork(Links = e, Nodes = n,
Source = 'from', Target = 'to', Value = 'weight', NodeID = 'id',
units = 'TWh', fontSize = 18, nodeWidth = 30)