2017-02-10 9 views
0

My Shiny App имеет несколько входов, которые зависят от количества используемых переменных. Ниже приведен упрощенный вариант, хотя и не работает. Я смог заставить пользовательский интерфейс обновляться на основе numericInput, используя функцию Make.UI, которую я использовал для создания uiOutput, но получение входных данных обратно на сервер за пределами моего набора навыков Shiny! Любые предложения будут ценны.Блестящий рендеринг с несколькими входами

Gwynn

library(shiny) 
D = matrix(runif(400), nrow = 20) 
colnames(D) = labs = sapply(1:20, function(i) {paste0("col",i)}) 

# Define UI for application that summarises data 
ui <- fluidPage(

    # Application title 
    titlePanel("Summaries"), 

    # Select columns to get fed into summary 
    tabsetPanel(
    tabPanel("Matching Variables Info", 
      sidebarPanel(

       numericInput("NoVars","No. of variables to summarize", 
          value = 3, min = 2, max = dim(D)[2]), 

       uiOutput("VarsInput") 
      ), 

      # Show summaries of columns choosen above 
      mainPanel(
       verbatimTextOutput("dataInfo") 
      ) 
    ) 
) 
) 


# Define the server code 
server <- function(input, output){ 

    Make.UI <- function(NoV){ 
    C = sapply(1:NoV, function(i){paste0("cols",i)}) 
    L = sapply(1:NoV, function(i){paste0("label",i)}) 

    output = tagList() 

    for(i in seq_along(1:NoV)){ 
     output[[i]] = tagList() 
     output[[i]][[1]] = selectInput(C[i], "Variable to summarize:", labs) 
     output[[i]][[2]] = textInput(L[i], label = "Label for variable:", 
            value = "Label for variable Here") 
    } ## for loop 

    output 
    } # closes Make.UI function 

    K <- reactive({ 
    input$NoVars 
    }) 

    output$VarsInput <- renderUI({ 
    Make.UI(K()) 
    }) 

    output$dataInfo <- renderPrint({ 
    C <- sapply(1:K(), function(i) {input[[paste0("cols",i)]]}) 
    ## the code in the line above doesn't work 

    summary(D[, C()]) 
    }) 

} 

# Return a Shiny app object 
shinyApp(ui = ui, server = server) 
+0

Вы действительно можете определить 'Make.UI()' вне вашей серверной функции. У него нет доступной выходной переменной? Для этого вам нужно будет использовать блестящий модуль. Более того, если вы хотите вернуть mutliple входные данные из renderUI, вы должны использовать 'tagList()'. К вашему окончательному вопросу о том, как использовать генерируемый вывод renderUI, является просто идентификатор, который вы назначили им на сервере. Должен работать, как только вы говорите вышеприведенные замечания. – BigDataScientist

+0

@BigDataScientist Я раньше не использовал tagList(). Знаете ли вы какие-либо примеры, похожие на это? Я использовал функции, определенные глобально в Shiny раньше и не испытывал никаких проблем, но, возможно, это другое. – nzgwynn

+0

А я вижу, ваш «выход» - это не блестящий выход, но вы сами определяете его, похоже, я немного устал. Хорошо, тогда я попытаюсь использовать 'output = tagList()' вместо этого. Кстати, код не полностью воспроизводимый, потому что u не предоставил то, что 'l.cols'is. Поэтому я отвечаю более общим образом. Надеюсь, он все равно поможет. – BigDataScientist

ответ

2

Как я писал в первом комментарии, я не уверен, о функции Make.UI(). Если вы действительно хотите сохранить ее как отдельную функцию, вы должны сделать ее реактивной. Или просто используйте его, как я сделал в приведенном ниже коде. Кроме того, в output$dataInfo <- renderPrint({ C не является функцией reactive(), поэтому вам нужно будет удалить скобки там.

library(shiny) 
D = matrix(runif(400), nrow = 20) 
colnames(D) = labs = sapply(1:20, function(i) {paste0("col",i)}) 

# Define UI for application that summarises data 
ui <- fluidPage(

    # Application title 
    titlePanel("Summaries"), 

    # Select columns to get fed into summary 
    tabsetPanel(
    tabPanel("Matching Variables Info", 
      sidebarPanel(

       numericInput("NoVars","No. of variables to summarize", 
          value = 3, min = 2, max = dim(D)[2]), 

       uiOutput("VarsInput") 
      ), 

      # Show summaries of columns choosen above 
      mainPanel(
       verbatimTextOutput("dataInfo") 
      ) 
    ) 
) 
) 


# Define the server code 
server <- function(input, output){ 

    K <- reactive({ 
    input$NoVars 
    }) 

    output$VarsInput <- renderUI({ 
    NoV = K() 
    C = sapply(1:NoV, function(i){paste0("cols",i)}) 
    L = sapply(1:NoV, function(i){paste0("label",i)}) 

    output = tagList() 

    for(i in seq_along(1:NoV)){ 
     output[[i]] = tagList() 
     output[[i]][[1]] = selectInput(C[i], "Variable to summarize:", labs) 
     output[[i]][[2]] = textInput(L[i], label = "Label for variable:", 
            value = "Label for variable Here") 
    } ## for loop 

    output 
    }) 

    output$dataInfo <- renderPrint({ 
    C <- sapply(1:K(), function(i) {input[[paste0("cols",i)]]}) 
    ## the code in the line above doesn't work 

    summary(D[, C]) 
    }) 

} 

# Return a Shiny app object 
shinyApp(ui = ui, server = server) 
+0

Спасибо! Это прекрасно работает и жаль, что я не совсем понял ваш первоначальный комментарий. – nzgwynn

+1

Я понял, как! Извините, я не знал! – nzgwynn

+0

Я обычно не комментирую ответы или решения, но для меня это очень впечатляет, и я думаю, что @BigDataScientist заслуживает большого уважения. –