Как сделать, чтобы изменения отражались во многих местах, когда ввод изменяется без ObserveEvent () в блестящем - PullRequest
0 голосов
/ 22 мая 2018

У меня есть входная переменная input$shop_id.Который используется для получения данных в функции сервера, используя:

 observeEvent(input$shop_id,{id<<-input$shop_id})
`Data=dbGetQuery(connection_name,paste0("SELECT * FROM tab_name WHERE id_shop=",id"))`

Эти данные используются для создания динамического интерфейса с использованием selectInput()

output$dependant=renderUI({
      selectInput("choice","Choose the Data you want to view",names(Data))
    })

Я не могу придуматьлогика расположения этих функций.Я не могу заставить его работать.Я создал пример данных и аналогичный пример кода для кого-то, чтобы примерить:

library(shiny)
library(ggplot2)
ui=fluidPage(
  column(6,uiOutput("shop_select")),
  column(6,uiOutput("cust_select")),
  column(6,uiOutput("select3")),
  column(12,offset=6,uiOutput("plot"))
)
server = function(input, output) {
  #sample data
  shopdata=data.frame(id=c(1,2,3,4,5,6,7,8,9,10),name=c("a","b","c","d","e","f","g","h","i","j")) 
  cdata=data.frame(id=c(123,465,6798,346,12341,45764,2358,67,457,5687,4562,23,12124,3453,12112),
                   name=c("sadf","porhg","wetgfjg","hwfhjh","yuigkug","syuif","rtyg","dygfjg","rturjh","kuser","zzsdfadf","jgjwer","jywe","jwehfhjh","kuwerg"),
                   shop=c(1,2,1,2,4,6,2,8,9,10,3,1,2,5,7),
                   bill_total=c(12341,123443,456433,234522,45645,23445,3456246,23522,22345,23345,23454,345734,23242,232456,345456),
                   crating=c(4,4.3,5,1.2,3.2,4,3.3,2.4,3.8,3,3.2,3.3,1.4,2.8,4.1))
    output$shop_select=renderUI({
    selectInput("shop_id","Shop ID",shopdata$id)
  })
    output$cust_select=renderUI({
      selectInput("cust_id","Customer ID",cdata$id,multiple = T)
    })
    output$select3=renderUI({
      a=input$shop_id
      selectInput("choice","Choose the Data you want to view",names(cdata))
    })
    output$plot=renderUI({
      renderPlot({
        require(input$choice)
        plotOutput(
      ggplot(cdata,aes(x=cust_id,y=input$choice))
    )})})
}
shinyApp(ui=ui,server=server)

Я знаю, что не ясно по этому вопросу.Исправления кода, который я разместил, более чем достаточно, чтобы очистить мои сомнения. По сути, мне просто нужно знать, какова логика, когда мы должны использовать при использовании renderUI(), который зависит от другого renderUI()

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Если вы хотите настроить последовательность операций поднабора, а затем вызвать renderUI() s для каждого подмножества, вам необходимо воспользоваться reactive({}) выражениями Shiny.

Реактивные выражения - это фрагменты кода, которыепроизводить переменные и их магия заключается в том, что они «следят» за любыми изменениями своих входных данных.Таким образом, в вашем случае вы выбираете shop_id в первом элементе пользовательского интерфейса, реактивное выражение обнаруживает это и автоматически обновляется!

Вот пример, показывающий обновление, просто выберите разные shop_id и посмотрите доступныеcust_id смена на лету.

library(shiny)
library(ggplot2)
library(tidyverse)
ui=fluidPage(
    column(6,uiOutput("shop_select")),
    column(6,uiOutput("cust_select")),
    column(6,uiOutput("select3")),
    column(12,offset=6,tableOutput("plot"))
)
server = function(input, output) {
    #sample data
    shopdata=data.frame(id=c(1,2,3,4,5,6,7,8,9,10),name=c("a","b","c","d","e","f","g","h","i","j")) 
    cdata=data.frame(id=c(123,465,6798,346,12341,45764,2358,67,457,5687,4562,23,12124,3453,12112),
                     name=c("sadf","porhg","wetgfjg","hwfhjh","yuigkug","syuif","rtyg","dygfjg","rturjh","kuser","zzsdfadf","jgjwer","jywe","jwehfhjh","kuwerg"),
                     shop=c(1,2,1,2,4,6,2,8,9,10,3,1,2,5,7),
                     bill_total=c(12341,123443,456433,234522,45645,23445,3456246,23522,22345,23345,23454,345734,23242,232456,345456),
                     crating=c(4,4.3,5,1.2,3.2,4,3.3,2.4,3.8,3,3.2,3.3,1.4,2.8,4.1))


    output$shop_select=renderUI({
        selectInput("shop_id","Shop ID",shopdata$id)
    })

    cdata_reactive <- reactive({
        req(input$shop_id)
        filter(cdata, shop == input$shop_id)
    })

    output$cust_select=renderUI({
        selectInput("cust_id","Customer ID",cdata_reactive()$id, multiple = T)
    })
    output$select3=renderUI({
        selectInput("choice","Choose the Data you want to view",names(cdata_reactive()))
    })
    output$plot <- renderTable({
        filter(cdata_reactive(), id %in% input$cust_id) %>%
                                   .[input$choice]
                                     })
}
shinyApp(ui=ui,server=server)
0 голосов
/ 22 мая 2018
  1. A renderUI генерирует UI элементов.Поэтому он может содержать только ui функций.Вам необходимо использовать его для генерации plotOutput, а затем отдельно использовать renderPlot для добавления контента.
  2. Имена, которые вы назначаете в вызове aes, являются именами переменных в предоставленном вами фрейме данных.Следовательно, x должно быть id, а не значением input$cust_id (которое должно называться input$cust_id, поскольку оно относится к входному объекту.
  3. input$choice возвращает строку, а не объекттаким образом, вы не можете использовать его обычно в aes (напомним, что если бы это был обычный фрейм данных, ваши значения aes были бы aes(x=id, y=choice), а не aes(x='id', y='choice'). Поэтому вам нужно использовать aes_ с функцией as.name, чтобыпреобразуйте эти строки в правильные имена переменных.
  4. Я думаю, что вы хотите сделать с input$cust_id фильтр cdata, чтобы включать только строки с выбранными значениями id. dplyr::filter - лучший способсделайте это.
  5. Наконец, вам не хватает geom_* в вашем вызове ggplot, необходимом для фактической визуализации ваших данных.

Если вы замените свой output$plot <- ... вызовприведенный ниже код должен работать так, как я думаю, вы хотите:

output$plot=renderUI({
        plotOutput('plotout')
        })

output$plotout <- renderPlot({
    ggplot(dplyr::filter(cdata, id %in% input$cust_id),
           aes_(x=as.name('id'),y=as.name(input$choice))) +
        geom_point()
})

Что касается вопроса в заголовке, вам нужно использовать observeEvent, только если вы хотите ограничить код в выражениизапускаться только при возникновении определенного триггера. Любое реактивное выражение (reactive, observe, render_ и т. Д.) Станут недействительными и обновятся при изменении любого реактивного значения (либо reactiveValues объекта, либо input$...).Если у вас есть input$ или реактивное значение в блоке render_, оно обновится, если они изменятся - не нужно observeEvent.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...