【问题标题】:R Shiny, - Passing Multiple User Inputs into a single dataframe in serverR Shiny, - 将多个用户输入传递到服务器中的单个数据框中
【发布时间】:2021-05-04 22:28:19
【问题描述】:

我必须承认我对 R-Shiny 比较陌生,如果这是一个非常基本的问题,我深表歉意。

我正在尝试创建一个 R-Shiny 应用程序,它接收与资产类别的预期年回报率、最大权重和最小权重相关的用户输入。理想情况下,我希望最终得到一个类似于下面的服务器数据帧,预期回报和权重可配置:

Asset Class Expected_Return Max_Weight Min_Weight
Equity 0.08 1.00 0.25
Bonds 0.02 0.75 0.10
Gold 0.03 0.20 0.00
Property 0.05 0.30 0.00
Cash 0.01 0.10 0.00

我的用户界面代码:

library(shiny)



ui <- fluidPage(
   fluidRow(
       column(width = 1, align="center",
              checkboxInput("equity_include", "Equity", value = TRUE, width = '100%')
       ),
       column(width = 5, align="center",
              numericInput("equity_er", "Global Expected Annual Return (%)", value = 0)
       ),
       column(width = 3, align="center",
              numericInput("equity_maxw", "Max Weight %", value = 100, min = 0, max = 100)
       ),
       column(width = 3, align="center",
              numericInput("equity_minw", "Min Weight %", value = 0, min = 0, max = 100)
       )
   ),
   fluidRow(
       column(width = 1, align="center",
              checkboxInput("bonds_include", "Bonds", value = TRUE, width = '100%')
       ),
       column(width = 5, align="center",
              numericInput("bonds_er", "Bonds Expected Annual Return (%)", value = 0)
       ),
       column(width = 3, align="center",
              numericInput("bonds_maxw", "Max Weight %", value = 100, min = 0, max = 100)
       ),
       column(width = 3, align="center",
              numericInput("bonds_minw", "Min Weight %", value = 0, min = 0, max = 100)
       )
   ),
   fluidRow(
       column(width = 1, align="center",
              checkboxInput("gold_include", "Gold", value = TRUE, width = '100%')
       ),
       column(width = 5, align="center",
              numericInput("gold_er", "Gold Expected Annual Return (%)", value = 0)
       ),
       column(width = 3, align="center",
              numericInput("gold_maxw", "Max Weight %", value = 100, min = 0, max = 100)
       ),
       column(width = 3, align="center",
              numericInput("gold_minw", "Min Weight %", value = 0, min = 0, max = 100)
       )
   ),
   fluidRow(
       column(width = 1, align="center",
              checkboxInput("property_include", "Property", value = TRUE, width = '100%')
       ),
       column(width = 5, align="center",
              numericInput("property_er", "Property Expected Annual Return(%)", value = 0)
       ),
       column(width = 3, align="center",
              numericInput("property_maxw", "Max Weight %", value = 100, min = 0, max = 100)
       ),
       column(width = 3, align="center",
              numericInput("property_minw", "Min Weight %", value = 0, min = 0, max = 100)
       )
   ),
   fluidRow(
       column(width = 1, align="center",
              checkboxInput("cash_include", "Cash", value = TRUE, width = '100%')
       ),
       column(width = 5, align="center",
              numericInput("cash_er", "Cash Expected Annual Return(%)", value = 0)
       ),
       column(width = 3, align="center",
              numericInput("cash_maxw", "Max Weight %", value = 100, min = 0, max = 100)
       ),
       column(width = 3, align="center",
              numericInput("cash_minw", "Min Weight %", value = 0, min = 0, max = 100)
       )
   ),
)

我的服务器代码:

server <- function(input, output) {
    library("tidyverse")
    library(plotly) # To create interactive charts
    library(timetk) # To manipulate the data series
    
    #Create Dataframe of User Inputs
    assets <- c("Equity", "Bonds", "Gold", "Property", "Cash")
    include <- c(input$equity_include, input$bonds_include, input$gold_include, input$property_include, input$cash_include)
    expected_return <- c(input$equity_er, input$bonds_er, input$gold_er, input$property_er, input$cash_er)
    max_weight <- c(input$equity_maxw, input$bonds_maxw, input$gold_maxw, input$property_maxw, input$cash_maxw)
    min_weight <- c(input$equity_minw, input$bonds_minw, input$gold_minw, input$property_minw, input$cash_minw)
    
    user_inputs <- data.frame(assets, include, expected_return, max_weight, min_weight)
   

不幸的是,我遇到了多个反应性错误,我无法使用典型的 reactive() 函数来解决这些错误。

非常感谢您在此问题上提供的任何帮助。

提前谢谢你!

【问题讨论】:

    标签: r shiny quantitative-finance shiny-reactivity


    【解决方案1】:

    我知道答案通常应该可以解决您的具体问题,但我很懒惰输入所有这些默认值,您可以使用可编辑的数据框来做到这一点,我喜欢为此使用 DT 包

    示例基于:https://yihui.shinyapps.io/DT-edit/

    library(shiny)
    library(DT)
    
    dt_output = function(title, id) {
      fluidRow(column(
        12, h1(paste0('Table ', sub('.*?([0-9]+)$', '\\1', id), ': ', title)),
        hr(), DTOutput(id)
      ))
    }
    render_dt = function(data, editable = 'cell', server = TRUE, ...) {
      renderDT(data, selection = 'none', server = server, editable = editable, ...)
    }
    
    shinyApp(
      ui = fluidPage(
        title = 'Double-click to edit table rows',
        
        dt_output('server-side processing (editable = "row")', 'x6'),
      ),
      
      server = function(input, output, session) {
        d6 = iris
        d6$Date = Sys.time() + seq_len(nrow(d6))
        
        options(DT.options = list(pageLength = 5))
        
        # server-side processing
        output$x6 = render_dt(d6, 'row')
        
        # edit a row
        observeEvent(input$x6_cell_edit, {
          d6 <<- editData(d6, input$x6_cell_edit, 'x6')
        })
        
    })
    

    【讨论】:

    • 感谢一百万,可编辑的数据框比我最初尝试做的要好得多。感谢您的帮助!
    【解决方案2】:

    如果你想保持旧方法用 reactive() 包围向量,然后通过调用函数等名称来使用

    library(shiny)
    library(DT)
    
    ui <- fluidPage(
      fluidRow(
        column(width = 1, align="center",
               checkboxInput("equity_include", "Equity", value = TRUE, width = '100%')
        ),
        column(width = 5, align="center",
               numericInput("equity_er", "Global Expected Annual Return (%)", value = 0)
        ),
        column(width = 3, align="center",
               numericInput("equity_maxw", "Max Weight %", value = 100, min = 0, max = 100)
        ),
        column(width = 3, align="center",
               numericInput("equity_minw", "Min Weight %", value = 0, min = 0, max = 100)
        )
      ),
      fluidRow(
        column(width = 1, align="center",
               checkboxInput("bonds_include", "Bonds", value = TRUE, width = '100%')
        ),
        column(width = 5, align="center",
               numericInput("bonds_er", "Bonds Expected Annual Return (%)", value = 0)
        ),
        column(width = 3, align="center",
               numericInput("bonds_maxw", "Max Weight %", value = 100, min = 0, max = 100)
        ),
        column(width = 3, align="center",
               numericInput("bonds_minw", "Min Weight %", value = 0, min = 0, max = 100)
        )
      ),
      fluidRow(
        column(width = 1, align="center",
               checkboxInput("gold_include", "Gold", value = TRUE, width = '100%')
        ),
        column(width = 5, align="center",
               numericInput("gold_er", "Gold Expected Annual Return (%)", value = 0)
        ),
        column(width = 3, align="center",
               numericInput("gold_maxw", "Max Weight %", value = 100, min = 0, max = 100)
        ),
        column(width = 3, align="center",
               numericInput("gold_minw", "Min Weight %", value = 0, min = 0, max = 100)
        )
      ),
      fluidRow(
        column(width = 1, align="center",
               checkboxInput("property_include", "Property", value = TRUE, width = '100%')
        ),
        column(width = 5, align="center",
               numericInput("property_er", "Property Expected Annual Return(%)", value = 0)
        ),
        column(width = 3, align="center",
               numericInput("property_maxw", "Max Weight %", value = 100, min = 0, max = 100)
        ),
        column(width = 3, align="center",
               numericInput("property_minw", "Min Weight %", value = 0, min = 0, max = 100)
        )
      ),
      fluidRow(
        column(width = 1, align="center",
               checkboxInput("cash_include", "Cash", value = TRUE, width = '100%')
        ),
        column(width = 5, align="center",
               numericInput("cash_er", "Cash Expected Annual Return(%)", value = 0)
        ),
        column(width = 3, align="center",
               numericInput("cash_maxw", "Max Weight %", value = 100, min = 0, max = 100)
        ),
        column(width = 3, align="center",
               numericInput("cash_minw", "Min Weight %", value = 0, min = 0, max = 100)
        )
      ),
      fluidRow(dataTableOutput("data_example"))
    )
    
    
    server <- function(input, output) {
      library("tidyverse")
      library(plotly) # To create interactive charts
      library(timetk) # To manipulate the data series
      
      #Create Dataframe of User Inputs
      assets <- c("Equity", "Bonds", "Gold", "Property", "Cash")
      include <- reactive(c(input$equity_include, input$bonds_include, input$gold_include, input$property_include,input$cash_include))
      expected_return <- reactive(c(input$equity_er, input$bonds_er, input$gold_er, input$property_er, input$cash_er))
      max_weight <- reactive(c(input$equity_maxw, input$bonds_maxw, input$gold_maxw, input$property_maxw, input$cash_maxw))
      min_weight <- reactive(c(input$equity_minw, input$bonds_minw, input$gold_minw, input$property_minw, input$cash_minw))
      
      #user_inputs <- data.frame(assets, include(), expected_return(), max_weight(), min_weight())
      output$data_example <- renderDataTable(data.frame(assets,include(),expected_return(),max_weight(),min_weight()))
    }
    
    shinyApp(ui,server)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-06
      • 2021-04-20
      • 1970-01-01
      • 2022-06-23
      • 2021-09-12
      • 2015-06-01
      • 2017-08-31
      • 2021-08-31
      相关资源
      最近更新 更多