R Shiny中的反应性Sankey图,具有多个数据帧作为输入



这是我第一次创建仪表板,遇到了一个似乎无法解决的问题。我已经创建了一个sankey图,我希望能够通过不同的数据帧(在本例中:level_1、level_2、level_3(交互式地更改其内容。我只在常规绘图中实践过这一点,其中输入来自一个数据帧中的一个变量,这是我在这段代码中的起点(例如,我有一个df$country,所以我在绘图中使用input$country-->然后我可以在仪表板侧边栏中从不同的国家中进行选择,以更改绘图的内容(。当输入必须来自单独的数据帧时,我不知道如何做到这一点。

我的代码:(在app.R中(

level_1 <- as.data.frame(matrix(sample(seq(0,40), 15, replace=T ), 3, 5))
level_2 <- as.data.frame(matrix(sample(seq(0,40), 20, replace=T ), 4, 5))
level_3 <- as.data.frame(matrix(sample(seq(0,40), 25, replace=T ), 5, 5))
levels <- list(level_1, level_2, level_3)
ui <- dashboardPage(
dashboardHeader(title = "title"),

dashboardSidebar(
selectInput("in_levels", "Levels", choices = levels) 

),
dashboardBody(
fluidRow(sankeyNetworkOutput("widget1"))
)
)
server <- function(input, output) { 

links <- input$in_levels %>%
rownames_to_column(var="source") %>% 
gather(key="target", value="value", -1) %>%
filter(value != 0)

nodes <- data.frame(
name=c(as.character(links$source), as.character(links$target)) %>% 
unique()
)

links$IDsource <- match(links$source, nodes$name)-1 
links$IDtarget <- match(links$target, nodes$name)-1

output$widget1 <- renderSankeyNetwork({
sankeyNetwork(Links = links, Nodes = nodes,
Source = "IDsource", Target = "IDtarget",
Value = "value", NodeID = "name", fontSize = 14, nodeWidth = 60,
fontFamily = "Arial", iterations = 0, sinksRight=TRUE)
})
}
shinyApp(ui, server)

我想也许创建一个所有数据帧的列表((、级别会有所帮助,但这不起作用。我得到这个错误:

Error : Can't access reactive value 'in_levels' outside of reactive consumer.
i Do you need to wrap inside reactive() or observer()?

我在谷歌上搜索了reactive((和observer((,试图找出我的下一步应该是什么,但我还没有找到解决方案。如果有人能给我一些建议,告诉我如何继续,做出改变或阅读一些东西来增加我的理解,我将不胜感激。

提前感谢!

如果要访问服务器中的任何input值,则需要使用反应上下文。shiny不允许您执行其他操作,但即使执行了,如果更新了input值,服务器端代码也不会更新以反映更改。由于您希望linksnodes都是动态的,并且都相互依赖,因此一个巧妙的解决方案可能是将这两个对象存储在如下列表中:

server <- function(input, output) { 

plot_data <- reactive({
# Perform all your computation inside this reactive!    
links <- input$in_levels %>%
rownames_to_column(var="source") %>% 
gather(key="target", value="value", -1) %>%
filter(value != 0)

nodes <- data.frame(
name = c(as.character(links$source), as.character(links$target)) %>% 
unique()
)

links$IDsource <- match(links$source, nodes$name)-1 
links$IDtarget <- match(links$target, nodes$name)-1
# Return the data in a list
list(links = links, nodes = nodes)
})

# Access the datasets by calling the reactive and then treating as a normal list
output$widget1 <- renderSankeyNetwork({
sankeyNetwork(Links = plot_data()$links, Nodes = plot_data()$nodes,
Source = "IDsource", Target = "IDtarget",
Value = "value", NodeID = "name", fontSize = 14, nodeWidth = 60,
fontFamily = "Arial", iterations = 0, sinksRight=TRUE)
})
}

这是未经测试的,因为我当前版本的R不支持network3d包。

反应性的概念很棘手,但如果你是shiny的新手,《掌握闪亮》的第三章应该很有启发性。

最新更新