代码之家  ›  专栏  ›  技术社区  ›  user113156

根据Shiny中的功能参数动态更改小部件/页面

  •  0
  • user113156  · 技术社区  · 4 年前

    我正在尝试生成一个依赖于函数某些参数的Shiny应用程序。如果我使用 quantmod 包下载数据,然后使用 TTR 包进行一些数据修改我想更改 numericInput() (添加/删除输入),具体取决于所选择的下拉值。

    我想复制类似于以下内容的内容。

    library(quantmod)
    library(TTR)
    
    sym <- "GOOG"
    
    data <- getSymbols(Symbols = sym, src = "yahoo", index.class = "POSIXct", from = "2018-01-01", to = "2019-01-01", auto.assign = FALSE)
    
    SMA(Cl(data), n = 5)
    EMA(Cl(data), n = 5)
    WMA(Cl(data), n = 5, wts = 1:5)
    

    我有一些数据,我对数据应用了3个函数 SMA , EMA WMA The SMA 美国发动机制造商协会 因为只需要一个论点,所以很简单 n 然而 WMA n 还有一个额外的论点 wts .

    我创建了一个基本的Shiny应用程序,在那里我修改了 Widgets 选项卡。我创建了4个字段。一个简单的文本字段、一个下拉菜单、一个指定参数 n 以及一个重量场。

    我想根据下拉菜单中的选择显示“正确”的指定输入字段。也就是说,表演 selectedN 对于自函数以来的所有选择 SMA , 美国发动机制造商协会 WMA 一切都取决于它,然而一旦 WMA 我希望用户能够输入一些权重/值。

    我在这里遇到了困难。

    1. 通过添加多个权重/数值并将其传递给 wts 价值在 reactive({}) 代码的一部分。
    2. 找到将此动态输入应用于 server 我在想的是申请 if 基于函数名的语句,但我想我已经看到了 更容易的 一些闪亮的教程上的方法。-因此,根据指定下拉列表中的函数,我想向用户展示所选函数的参数。

    任何朝着正确方向的推动都会很棒。

    闪亮代码:

    ## app.R ##
    library(shiny)
    library(shinydashboard)
    library(quantmod)
    library(TTR)
    
    ui <- dashboardPage(
        dashboardHeader(title = "Basic dashboard"),
        dashboardSidebar(
            sidebarMenu(
                menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard")),
                menuItem("Widgets", tabName = "widgets", icon = icon("th"))
            )
        ),
        dashboardBody(
            tabItems(
                # First tab content
                tabItem(tabName = "dashboard",
                        fluidRow(
                            box(plotOutput("plot1", height = 250)),
                            
                            box(
                                title = "Controls",
                                sliderInput("slider", "Number of observations:", 1, 100, 50)
                            )
                        )
                ),
                
                # Second tab content
                tabItem(tabName = "widgets",
                        fluidPage(
                            titlePanel(title = h2("Algo Backtester", align = "center")),
                            sidebarPanel(
                                textInput("sym", "Symbol", "MSFT"),
                                selectInput(inputId = "selectDropdown", label = "dropdownChoice", choices = c("SMA", "EMA", "WMA")),
                                numericInput(inputId = "selectN", label = "selectedN", value = 3),
                                numericInput(inputId = "weights", label = "Weights", value = 1)              # stuck here with adding multiple weights
                            ),
                            mainPanel(
                                tableOutput("modData"),
                                
                            )
                        )
                )
                )
            )
        )
    
    server <- function(input, output) {
        set.seed(122)
        histdata <- rnorm(500)
        
        output$plot1 <- renderPlot({
            data <- histdata[seq_len(input$slider)]
            hist(data)
        })
        
        output$out <- reactive({
            selectedDropdown <- input$selectDropdown
            data <- getSymbols(Symbols = input$sym, src = "yahoo", index.class = "POSIXct", from = "2018-01-01", to = "2019-01-01", auto.assign = FALSE)
            n = input$selectN
            wts = 1:5                                   # would like to modify here                             
            # Apply selection to "data"
            if(selectDropdown == "SMA"){
                SMA(Cl(data), n = n)
            } 
            if(selectDropdown == "EMA"){
                EMA(Cl(data), n = n)
            }
            if(selectDropdown == "WMA"){
                WMA(Cl(data), n = n, wts = wts)
            }
            
            
        })
        
        output$modData <- renderTable({
            head(output$out())
        })
        
        
    }
    
    shinyApp(ui, server)
    
    0 回复  |  直到 4 年前
        1
  •  2
  •   starja    4 年前

    要动态生成UI元素,您需要使用 renderUI 在服务器中,并将其分配给 uiOutput 在UI功能中。因为你只想在以下情况下渲染元素 WMA 功能已选择,您可以使用 req(input$selectDropdown == "WMA") renderUI 电话。 req 评估表达式是否为“truthy”,并且仅在满足条件时执行以下代码。

    由于您只有3种不同的功能选择,我认为您可以使用 if 这里的条款完全可以。

    你的代码还有其他问题:

    • 如果你生成一个 reactive 函数,您只需将其分配给函数名称,而不是 output$functionname
    • 拼写错误 selectDropdown 而不是 selectedDropdown
    • 我不知道什么是合理的输入 wts 争论。 numericInput 只返回一个值,但你需要一个长度为的向量 x 我刚用过 rep(input$weights, times = nrow(data)) 使其发挥作用
    library(shiny)
    library(shinydashboard)
    library(quantmod)
    library(TTR)
    
    ui <- dashboardPage(
      dashboardHeader(title = "Basic dashboard"),
      dashboardSidebar(
        sidebarMenu(
          menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard")),
          menuItem("Widgets", tabName = "widgets", icon = icon("th"))
        )
      ),
      dashboardBody(
        tabItems(
          # First tab content
          tabItem(tabName = "dashboard",
                  fluidRow(
                    box(plotOutput("plot1", height = 250)),
                    
                    box(
                      title = "Controls",
                      sliderInput("slider", "Number of observations:", 1, 100, 50)
                    )
                  )
          ),
          
          # Second tab content
          tabItem(tabName = "widgets",
                  fluidPage(
                    titlePanel(title = h2("Algo Backtester", align = "center")),
                    sidebarPanel(
                      textInput("sym", "Symbol", "MSFT"),
                      selectInput(inputId = "selectDropdown", label = "dropdownChoice", choices = c("SMA", "EMA", "WMA")),
                      numericInput(inputId = "selectN", label = "selectedN", value = 3),
                      uiOutput(outputId = "weights_UI")
                    ),
                    mainPanel(
                      tableOutput("modData"),
                      
                    )
                  )
          )
        )
      )
    )
    
    server <- function(input, output) {
      set.seed(122)
      histdata <- rnorm(500)
      
      output$plot1 <- renderPlot({
        data <- histdata[seq_len(input$slider)]
        hist(data)
      })
      
      output$weights_UI <- renderUI({
        req(input$selectDropdown == "WMA")
        
        numericInput(inputId = "weights", label = "Weights", value = 1)
      })
      
      out <- reactive({
        selectedDropdown <- input$selectDropdown
        data <- getSymbols(Symbols = input$sym, src = "yahoo", index.class = "POSIXct", from = "2018-01-01", to = "2019-01-01", auto.assign = FALSE)
        
        n = input$selectN
        # wts = 1:5                                   # would like to modify here                             
        # Apply selection to "data"
        if(selectedDropdown == "SMA"){
          SMA(Cl(data), n = n)
        } 
        if(selectedDropdown == "EMA"){
          EMA(Cl(data), n = n)
        }
        if(selectedDropdown == "WMA"){
          WMA(Cl(data), n = n, wts = rep(input$weights, times = nrow(data)))
        }
        
        
      })
      
      output$modData <- renderTable({
        head(out())
      })
      
      
    }
    
    shinyApp(ui, server)