循环中的Shiny R renderPrint使用RenderUI只更新输出

时间:2015-09-22 13:37:35

标签: r shiny

我正在尝试从多个文本输入动态呈现多个文本输出。我尝试使用this very helpfull examplethis one too。 这个conversation 也很有帮助。 但是当我尝试在下面的脚本上调整这些示例时,我遇到了输出更新的问题。显然,只读取和更新了最后一个元素。这可能是反应性问题,但似乎很难将reactive{()}renderUI{()}函数关联起来。

rm(list = ls())
library(shiny)

creatDataElem <- function(ne, input) {
    x1 <- lapply(1:ne, function(i) {
    textInput(paste0("elemName", i),
          label = h4(strong("Name of dataset element")),
          value = "")
   })
   return(x1)
}

ui = (fluidPage(
         sidebarLayout(
           sidebarPanel(
             sliderInput("elemNb",
                         "Number of elements", value = 1, min = 1,
                         max = 3)
             ,
             conditionalPanel(
               condition = "input.elemNb == 1",
               creatDataElem(1)
             ),
             conditionalPanel(
               condition = "input.elemNb == 2",
               creatDataElem(2)
             ),
             conditionalPanel(
               condition = "input.elemNb == 3",
               creatDataElem(3)
             )
           ),
         mainPanel(
           uiOutput("nameElem")
         )
       )
      )
   )

server = function(input, output, session) {

max_elem <- 3
# Name

output$nameElem <-renderUI({
  nameElem_output_list <- lapply(1:input$elemNb, function(i) {
    elemName <- paste0("elemName", i)
    tags$div(class = "group-output",
             verbatimTextOutput(elemName)
    )
  })
  do.call(tagList, nameElem_output_list)
})

for (i in 1:max_elem) {
  local({
    force(i)
    my_i <- i
    elemName <- paste0("elemName", my_i)
    output[[elemName]] <- renderPrint(input[[elemName]])
  })
}
}

runApp(list(ui = ui, server = server))

使用reactive({})函数的想法是添加一个独立的对象(在这种情况下是一个函数),如:

nameElem <- reactive({
  if (input$goElem == 0) {
    return()
  } else {
    isolate({
      if (is.null(input$elemName)) {
         return()
      } else if (test(input$elemName)) {
         return("TEST RESULT")
      } else {
         return(input$elemName)
      }
   })
 }
})

并在此对象上使用renderUI(使用ActionButton)。 所以,如果有人知道为什么输出不会返回好的对象......

2 个答案:

答案 0 :(得分:1)

我认为您的一个问题是您的creatDataElem函数是这样的,当使用参数ne = 3调用它时,会再次创建第一个和第二个textInput元素(并且它们的值“丢失”)。

无论如何,我认为一种解决方案是将这些textInput元素创建为“uiOutput”。

你会在下面找到一个可能的解决方案(我认为)可以做你想要的。

莉莎

rm(list = ls())
library(shiny)

ui = (fluidPage(
  sidebarLayout(
    sidebarPanel(
      sliderInput("elemNb",
                  "Number of elements", value = 1, min = 1,
                  max = 3),
      uiOutput("myUI")    
    ),
    mainPanel(
      uiOutput("nameElem")
    )
  )
)
)

server = function(input, output, session) {
  output$myUI=renderUI({
    w=""
    for (i in 1:input$elemNb){
      w=paste0(w,
               textInput(paste0("elemName",i),label='Name of dataset element'))
    }
    HTML(w)
  })
  output$nameElem <-renderUI({
    elems=c("<div>")
    for(i in 1:input$elemNb){
      elems=paste(elems,"</div><div>",input[[paste0("elemName",i)]])
    }
        elems=paste0(elems,"</div>")
        HTML(elems)
      })
}

runApp(list(ui = ui, server = server))

答案 1 :(得分:0)

找到了解决方案:

library(readr)
library(dplyr)
library(shiny)

df <-  data.frame(symbol = 1:10)

uiOutput("myUI")

createUI <- function(dfID, symbol) {
    div(class="flex-box",paste0(symbol, " - 10"))
  }
output$myUI <- renderUI({

    w <- lapply(seq_len(nrow(df)), function(i) {
      createUI(i, df[i,"symbol"])
    })

    do.call(fluidPage,w)
})