R:循环和IF语句内的选择性输出赋值
我有一个闪亮的应用程序,它调用一个脚本,在每次迭代中迭代生成一个图形。我需要显示每个绘图,并尝试使用recordPlot将每个绘图保存到列表中,并单独调用每个元素,但应用程序稍后无法识别对象。然后我还尝试在IF语句中包含不同的输出,但我的算法只为所有输出生成最后一个图,就像IF语句被忽略一样,我不知道如何处理它。以下是我的代码的简化:R:循环和IF语句内的选择性输出赋值,r,if-statement,while-loop,shiny,output,R,If Statement,While Loop,Shiny,Output,我有一个闪亮的应用程序,它调用一个脚本,在每次迭代中迭代生成一个图形。我需要显示每个绘图,并尝试使用recordPlot将每个绘图保存到列表中,并单独调用每个元素,但应用程序稍后无法识别对象。然后我还尝试在IF语句中包含不同的输出,但我的算法只为所有输出生成最后一个图,就像IF语句被忽略一样,我不知道如何处理它。以下是我的代码的简化: library(shiny) ui <- fluidPage( # Main panel for displaying outputs ----
library(shiny)
ui <- fluidPage(
# Main panel for displaying outputs ----
mainPanel(
actionButton("exec", "Start!!"),
tagList(tags$h4("First iteration:")),
plotOutput('PlotIter1'),
tags$hr(),
tagList(tags$h4("Second iteration:")),
plotOutput('PlotIter2'),
tags$hr(),
tagList(tags$h4("Third iteration:")),
plotOutput('PlotIter3'),
tags$hr())
)
server <- function(input, output) {
ii <- 1
observeEvent(input$exec,{
continue <- TRUE
while(continue==TRUE){
if(ii == 1){
output$PlotIter1<-renderPlot({
plot(rep(ii,50),main=ii)
})
}
if(ii == 2){
output$PlotIter2<-renderPlot({
plot(rep(ii,50),main=ii)
})
}
if(ii == 3){
output$PlotIter3<-renderPlot({
plot(rep(ii,50),main=ii)
})
}
ii <- ii+1
if(ii == 4){continue <- FALSE}
}
})
}
shinyApp(ui, server)
库(闪亮)
ui实际上,在使用renderXXX
、reactive
或observe
内部循环时,可能会遇到一些问题,因为计算太慢。根据我的经验,最干净的解决方法是像这样使用lappy和loop-over
但是,对于您的情况,一个更快的解决方法是按照第一个答案中的建议使用local
。请注意,ii实际上,在使用renderXXX
、reactive
或observe
内部循环时,可能会遇到一些问题,这是由于延迟计算造成的。根据我的经验,最干净的解决方法是像这样使用lappy和loop-over
但是,对于您的情况,一个更快的解决方法是按照第一个答案中的建议使用local
。请注意,iiI建议使用,而(或类似)回路缺少一些反应性电位。事实上,看起来您试图在shiny的依赖性/反应性层中强制绘制顺序
我认为应该有三个独立的块,在R/Shining允许的范围内同时迭代:
library(shiny)
ui <- fluidPage(
# Main panel for displaying outputs ----
mainPanel(
actionButton("exec", "Start!!"),
tagList(tags$h4("First iteration:")),
plotOutput('PlotIter1'),
tags$hr(),
tagList(tags$h4("Second iteration:")),
plotOutput('PlotIter2'),
tags$hr(),
tagList(tags$h4("Third iteration:")),
plotOutput('PlotIter3'),
tags$hr()
)
)
server <- function(input, output) {
output$PlotIter1 <- renderPlot({
plot(rep(1,50),main=1)
})
output$PlotIter2 <- renderPlot({
plot(rep(2,50),main=2)
})
output$PlotIter3 <- renderPlot({
plot(rep(3,50),main=3)
})
}
shinyApp(ui, server)
当然,这种方法只适用于曲线图相对一致且变化较小的情况。否则,上面的第一个版本可能更合适。我建议使用,而(或类似)回路缺少一些反应潜力。事实上,看起来您试图在shiny的依赖性/反应性层中强制绘制顺序
我认为应该有三个独立的块,在R/Shining允许的范围内同时迭代:
library(shiny)
ui <- fluidPage(
# Main panel for displaying outputs ----
mainPanel(
actionButton("exec", "Start!!"),
tagList(tags$h4("First iteration:")),
plotOutput('PlotIter1'),
tags$hr(),
tagList(tags$h4("Second iteration:")),
plotOutput('PlotIter2'),
tags$hr(),
tagList(tags$h4("Third iteration:")),
plotOutput('PlotIter3'),
tags$hr()
)
)
server <- function(input, output) {
output$PlotIter1 <- renderPlot({
plot(rep(1,50),main=1)
})
output$PlotIter2 <- renderPlot({
plot(rep(2,50),main=2)
})
output$PlotIter3 <- renderPlot({
plot(rep(3,50),main=3)
})
}
shinyApp(ui, server)
当然,这种方法只适用于曲线图相对一致且变化较小的情况。否则,上面的第一个版本可能更合适。对于将来的某个人来说,我最终提出的解决方案是将数据结构更改为一个列表,其中存储了每次迭代的结果,然后,列表中的每个元素在一个周期内被绘制到相应的渲染图中。当然,如果没有埃文斯和塞西莉亚指出的非常重要的事情,这是不可能的。因此,这种方法提供了以下server.R
功能:
server <- function(input, output){
y <- list()
#First data set
y[[1]] <- rnorm(10,20,2)
#Simple example of iteration results storage in the list simulating an iteration like procces
for(i in 2:3){
y[[i]]=y[[i-1]]+100
}
#Plots of every result
for(j in 1:3){
local({
thisi <- j
plotname <- sprintf("PlotIter%d", thisi)
output[[plotname]] <<- renderPlot({
plot(y[[thisi]], main=paste0("Iteration: ",thisi,", mean: ",round(mean(y[[thisi]]),2)
))
abline(h=mean(y[[thisi]]),col=thisi)
})
})
}
}
server对于未来的某个人,我最终提出的解决方案是将数据结构更改为一个列表,其中存储了每次迭代的结果,然后,列表中的每个元素都被绘制到For
周期内相应的渲染图中。当然,如果没有埃文斯和塞西莉亚指出的非常重要的事情,这是不可能的。因此,这种方法提供了以下server.R
功能:
server <- function(input, output){
y <- list()
#First data set
y[[1]] <- rnorm(10,20,2)
#Simple example of iteration results storage in the list simulating an iteration like procces
for(i in 2:3){
y[[i]]=y[[i-1]]+100
}
#Plots of every result
for(j in 1:3){
local({
thisi <- j
plotname <- sprintf("PlotIter%d", thisi)
output[[plotname]] <<- renderPlot({
plot(y[[thisi]], main=paste0("Iteration: ",thisi,", mean: ",round(mean(y[[thisi]]),2)
))
abline(h=mean(y[[thisi]]),col=thisi)
})
})
}
}
server感谢您的时间和努力,但是,也许我的MWE遇到了问题过于简单化的问题,因此第一种方法不适用于我的特定情况。第二个解决了我的问题。非常感谢。从你的问题和你接受的答案来看,你似乎只希望情节被完成一次,而且只有一次,永远不会更新。正确吗?是的,正确,我希望每次迭代都生成一个绘图,并以某种方式将该绘图存储在相应的渲染图中,以供以后显示。在任何情况下,尽管local({})
解决方案在我的MWE上运行良好,但我的程序仍然在向我显示最后生成的绘图n倍于对应于相应迭代运行的绘图的开头。“for later show”对我来说没有意义。代码立即生成三个绘图,立即显示绘图,并且永远不会再次生成它们。这个“以后”的概念不符合我对它的看法。我理解您的实际用例可能与这个示例不同,所以我“了解”了更多的情况,但我并不完全遵循。(另外,我的答案对我有效;如果你说另一个答案对你的实际代码无效,那么也许你不应该接受它,而是编辑你的MWE/问题并重试?)可以忽略“供以后显示”部分,抱歉。我已经编辑了我的MWE和问题。谢谢你的时间和努力,但是,也许我的MWE遇到了问题过于简单化的问题,所以第一种方法不适用于我的特殊情况。第二个解决了我的问题。非常感谢。从你的问题和你接受的答案来看,你似乎只希望情节被完成一次,而且只有一次,永远不会更新。正确吗?是的,正确,我希望每次迭代都生成一个绘图,并以某种方式将该绘图存储在相应的渲染图中,以供以后显示。在任何情况下,尽管local({})
解决方案在我的MWE上运行良好,但我的程序仍然在向我显示最后生成的绘图n倍于对应于相应迭代运行的绘图的开头。“for later show”对我来说没有意义。代码立即生成三个绘图,立即显示绘图,并且永远不会再次生成它们。这个“以后”的概念不符合我对它的看法。我理解您的实际用例可能与这个示例不同,所以我“了解”了更多的情况,但我并不完全遵循。(另外,我的答案对我有用;如果你说另一个答案对你的实际代码不起作用,那么也许你不应该接受它,而是编辑你的MWE/问题,然后再试一次
library(evaluate)
plotList <- list()
i <- 0
evaluate(
function() {
source("path/to/script.R")
},
output_handler = output_handler(
graphics = function(plot) {
i <- i + 1
plotList[[i]] <- plot
}
)
)
library(shiny)
ui <- fluidPage(
# Main panel for displaying outputs ----
mainPanel(
actionButton("exec", "Start!!"),
tagList(tags$h4("First iteration:")),
plotOutput('PlotIter1'),
tags$hr(),
tagList(tags$h4("Second iteration:")),
plotOutput('PlotIter2'),
tags$hr(),
tagList(tags$h4("Third iteration:")),
plotOutput('PlotIter3'),
tags$hr()
)
)
server <- function(input, output) {
output$PlotIter1 <- renderPlot({
plot(rep(1,50),main=1)
})
output$PlotIter2 <- renderPlot({
plot(rep(2,50),main=2)
})
output$PlotIter3 <- renderPlot({
plot(rep(3,50),main=3)
})
}
shinyApp(ui, server)
server <- function(input, output) {
for (i in 1:3) {
local({
thisi <- i
plotname <- sprintf("PlotIter%d", thisi)
output[[plotname]] <<- renderPlot({
plot(rep(thisi, 50), main=thisi)
})
})
}
}
server <- function(input, output){
y <- list()
#First data set
y[[1]] <- rnorm(10,20,2)
#Simple example of iteration results storage in the list simulating an iteration like procces
for(i in 2:3){
y[[i]]=y[[i-1]]+100
}
#Plots of every result
for(j in 1:3){
local({
thisi <- j
plotname <- sprintf("PlotIter%d", thisi)
output[[plotname]] <<- renderPlot({
plot(y[[thisi]], main=paste0("Iteration: ",thisi,", mean: ",round(mean(y[[thisi]]),2)
))
abline(h=mean(y[[thisi]]),col=thisi)
})
})
}
}