如何解决R Shiny 中的反应式桑基图,以多个数据帧作为输入
这是我第一次创建仪表板,但遇到了一个我似乎无法解决的问题。我创建了一个桑基图,我希望能够通过不同的数据帧交互地更改其内容(在本例中: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,20,4,5))
level_3 <- as.data.frame(matrix(sample(seq(0,25,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()?
我在 google 上搜索了reactive() 和observer() 试图找出下一步应该做什么,但我还没有找到解决方案。如果有人能就如何进行、进行更改或阅读一些内容以增加我的理解提供建议,我将不胜感激。
提前致谢!
解决方法
如果您想访问服务器中的任何 input
值,您需要使用响应式上下文。 shiny
不允许您执行其他操作,但即使这样做,如果更新了 input
值,服务器端代码也不会更新以反映更改。由于您希望 links
和 nodes
都是动态的并且相互依赖,一个巧妙的解决方案可能是将两个对象存储在一个列表中,如下所示:
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
,chapter 3 of Mastering Shiny 应该很有启发性。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。