【问题标题】:Dynamic UiOutput Causing Issue when Adding Inputs to a DataFrame Shiny将输入添加到 DataFrame Shiny 时动态 UiOutput 导致问题
【发布时间】:2019-08-10 21:00:07
【问题描述】:

我有一个应用程序,用户可以在其中选择她想要分析的股票。根据选择的股票数量,应用程序将呈现等量的 UIOuputs,用户可以在其中选择每只股票的权重。因此,例如,如果您选择 6 只股票进行分析,则 6 个 uioutput 将呈现每个要求选择权重。

我遇到的问题是,我想用输入创建一个数据框。因此,如果用户选择权重为 0.50 和 0.50 的 AAPl 和 MSFT。我想创建一个df:

Ticker  Weight
AAPL    .50
MSFT    .50

但是,当我尝试创建数据框时,我得到一个错误,输入长度不同。我相信这是因为闪亮的反应性如何工作(未排序)。任何输入将不胜感激。下面是应用程序。

library(shiny)
library(purrr)
library(tidyverse)
library(DT)
tickers = c("SPY", "IWM", "QQQ", "TLT", "AGG", "GLD", "SLV")

ui <- fluidPage(

    # Application title
    titlePanel("Portfolio Builder"),

    #select the stocks you want to analyze
    mainPanel(
       selectizeInput("mult", "chose stock", choices = tickers, selected = "SPY", multiple = T),
       uiOutput("plo"),
       dataTableOutput("dataTab")
    )


)

# Define server logic required to draw a histogram
server <- function(input, output) {

 output$plo = renderUI({
     z = length(input$mult)
     name = input$mult
     map2(seq(z), name,  ~ numericInput(inputId = paste0("hey",.x), label = paste("weight", .y), value = 10))

     })

 weights = reactiveValues()

 observe({weights$current = map(seq(length(input$mult)),~input[[paste0("hey",.x)]]) %>% unlist()})

 mat = reactive({
   #if(length(weights$current) == length(input$mult)){
   df = data.frame(ticker = input$mult, weight = weights$current) %>% mutate(weightPct = weights$current/sum(weights$current))
  # }else{NULL}
 })

 output$dataTab = renderDataTable({
   mat()
 })


observe(print(weights$current))
observe(print(input$mult))



}

【问题讨论】:

  • 我添加了:output$my_df &lt;- renderDataTable({mat()}) 到服务器,dataTableOutput("my_df") 到 UI。它似乎正确地创建了数据框。我错过了什么?
  • 嗨 Ryan 我已经更新了代码以添加到您的数据表 + 转换中。当您添加新库存时,您现在应该会看到错误。我在#if(length...) 中添加了一个解决方案。但是我认为这个解决方案不是正确的“闪亮方式”
  • 需要的可以加req()。我对你的观察电话感到困惑。如果一切都在响应式上下文中,则不必使用观察者。

标签: r shiny purrr


【解决方案1】:

我将您的 observe()reactiveValues() 转换为单个 reactive() 对象。通过这种方式,它可以对变化做出反应,而不会产生您所拥有的复杂性。另一个很大的不同是我将weights 对象转换为一个列表,但我认为它仍然应该很容易理解。由于用户输入的长度和权重暂时不匹配,数据框错误仍然存​​在,因此我返回了您已经拥有的长度检查:

library(shiny)
library(purrr)
library(tidyverse)
library(DT)
tickers = c("SPY", "IWM", "QQQ", "TLT", "AGG", "GLD", "SLV")
suppressWarnings()

ui <- fluidPage(

  # Application title
  titlePanel("Portfolio Builder"),

  #select the stocks you want to analyze
  mainPanel(
    selectizeInput("mult", "chose stock", choices = tickers, selected = "SPY", multiple = T),
    uiOutput("plo"),
    dataTableOutput("dataTab")
  )


)

# Define server logic required to draw a histogram
server <- function(input, output) {

  output$plo = renderUI({
    z = length(input$mult)
    name = input$mult
    map2(seq(z), name,  ~ numericInput(inputId = paste0("hey",.x), label = paste("weight", .y), value = 10))

  })

  weights = reactive({
    req(input$mult)
    list(current = map(seq(length(input$mult)),~input[[paste0("hey",.x)]]) %>% unlist())
  })


  mat = reactive({
    req(weights()$current)
    if(length(weights()$current) == length(input$mult)){
      df = data.frame(ticker = input$mult, weight = weights()$current) %>% mutate(weightPct = weights()$current/sum(weights()$current))
    }
  })

  output$dataTab = renderDataTable({
    req(mat())
    mat()
  })


}

shinyApp(ui, server)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-05
    • 1970-01-01
    • 2018-06-10
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多