我正在构建一个简单的闪亮应用,以显示用户选择的网络上的中心度量。用户选择网络格式,网络文件和要计算的中心度量,然后单击按钮布局并可视化节点大小与节点中心性成正比的图形。在renderPlot
输出中,我隔离了按钮的所有输入,因此只有在用户选择了相关信息(格式,文件,度量)并单击可视化按钮时才进行计算。它的工作原理但存在以下问题:每次单击可视化按钮时,都会重新计算布局,并以不同的方式显示网络。我想避免这种行为。我试图在reactive
调用中包含布局计算(请参阅注释代码),但隔离失败。
因此,我能够隔离但不能使代码被动,或者让它在没有隔离的情况下被动反应。
UI代码如下:
shinyUI(fluidPage(
titlePanel("Visualize and compare centrality measures"),
sidebarLayout(
sidebarPanel(
selectInput("format", label = h4("Select graph format"),
choices = c("gml", "graphml", "edgelist", "pajek", "ncol", "lgl",
"dimacs", "graphdb", "dl")),
br(),
fileInput("graph", label = h4("Load graph")),
br(),
selectInput("centrality", label = h4("Select centrality measure"),
choices = c("degree", "eigenvector", "Katz")),
br(),
conditionalPanel(
condition = "input.centrality == 'Katz'",
numericInput("alpha",
label = h4("Alpha"), min=0, step = 0.05,
value = 1)),
actionButton("plot", "Visualize")
),
mainPanel(plotOutput("net"))
)
))
服务器代码如下:
library(igraph)
# mapping k from [x,y] in [w,z] with f(k) = w + (z-w) * (k-x)/(y-x)
map = function(k,x,y,w,z) {if (x != y) w + (z-w) * (k-x)/(y-x) else (w+z)/2}
shinyServer(
function(input, output) {
# read input graph
# g = reactive({read.graph(file=input$graph$datapath, format=input$format)});
# compute layout
# coords = reactive({layout.fruchterman.reingold(g)});
output$net = renderPlot({
if (input$plot > 0) {
g = isolate(read.graph(file=input$graph$datapath, format=input$format))
coords = layout.fruchterman.reingold(g)
cent = isolate(switch(input$centrality,
"degree" = degree(g),
"eigenvector" = evcent(g)$vector,
"Katz" = alpha.centrality(g, alpha = input$alpha)))
plot(g, layout=coords, vertex.label=NA, vertex.size = map(cent, min(cent), max(cent), 1, 10))
}
})
}
)
答案 0 :(得分:1)
我的回答(感谢Nicola):
<强> UI.R 强>
shinyUI(fluidPage(
titlePanel("Visualize and compare centrality measures"),
sidebarLayout(
sidebarPanel(
selectInput("format", label = h4("Graph format"),
choices = c("gml", "graphml", "edgelist", "pajek", "ncol", "lgl",
"dimacs", "graphdb", "dl")),
br(),
fileInput("graph", label = h4("Graph file")),
br(),
selectInput("centrality", label = h4("Centrality measure"),
choices = c("degree", "eigenvector", "Katz", "pagerank")),
br(),
conditionalPanel(
condition = "input.centrality == 'Katz' || input.centrality == 'pagerank'",
numericInput("alpha",
label = h4("Damping"), min=0, max = 1, step = 0.05,
value = 0.85), br()),
actionButton("plot", "Visualize")
),
mainPanel(plotOutput("net"))
)
))
<强> Server.R 强>
library(igraph)
map = function(k,x,y,w,z) {if (abs(x - y) > 10^-3) w + (z-w) * (k-x)/(y-x) else (w+z)/2}
shinyServer(
function(input, output) {
# read and cache the graph
inputGraph = reactive({
inFile = input$graph
if (!is.null(inFile))
read.graph(file=inFile$datapath, format=input$format)
})
# read and cache the layout
inputCoords = reactive({layout.fruchterman.reingold(inputGraph())});
# render the plot
output$net = renderPlot({
# viualize button
input$plot
# isolate input graph
g = isolate(inputGraph())
if (!is.null(g)) {
coords = isolate(inputCoords())
cent = isolate(switch(input$centrality,
"degree" = degree(g),
"eigenvector" = evcent(g)$vector,
"Katz" = alpha.centrality(g, alpha = input$alpha),
"pagerank" = page.rank(g, damping = input$alpha)$vector))
top = which.max(cent)
V(g)$color = "skyblue"
V(g)[top]$color = "red"
plot(g, layout=coords, vertex.label=NA, vertex.size = map(cent, min(cent), max(cent), 1, 10))
}
})
}
)