繁体   English   中英

在闪亮/闪亮的仪表板中为反应性数据框创建新列

[英]Creating new column for reactive dataframe in shiny/shiny dashboard R

在我的shinyApp服务器中,我根据输入创建了一个数据帧。 但是,我想添加一个新列,该列使用该数据帧的两列。

server <- function(input, output, session) {
  l.out <- reactive({
    BatchGetSymbols(tickers = input$stock, 
                first.date = Sys.Date() - as.integer(input$length),
                last.date = Sys.Date())
  })
  stock_info <- reactive({
    l.out()$df.tickers
  })
  stock_info()$return <- reactive({
    rep(0, length(stock_info()$ref.date))
  })
  stock_info()$return <- reactive({
    for (i in 2:length(stock_info()$ref.date)){
      stock_info()$return[i] <- ((stock_info()$price.close[i] - 
stock_info()$price.close[i - 1]) / stock_info$price.close[i - 1])
    }
  })

我已经尝试过这样的做法,直到我尝试创建stock_info()$ return,然后我一直得到NULL留下赋值的错误。 有小费吗?

我不熟悉BatchGetSymbols包,但下面示例中的概念也适用于您的用例。

首先,由于缺乏优雅的说法,我很确定表达方式......

  stock_info()$return <- reactive({
    rep(0, length(stock_info()$ref.date))
  })

......实际上并不是反应性对象和相关语法的shiny

看起来你可以通过将一堆中间步骤压缩成单个表达式来大大简化代码。 如果您只有一组反应数据,您将在所有输出中使用,这可能是一种更直接的方法。

library(shiny)

ui <- fluidPage(
  textInput('stock','stock',"GE"),
  sliderInput('length', 'length', min = 1, max = 10, value = 5),
  dataTableOutput('my_table')
)

server <- function(input, output, session) {

  ## This will update whenever either input$length or input$stock change
  stock_info <- reactive({

    length <- as.integer(input$length)

    temp_stock_info <- data.frame(stock = input$stock,
                                  foo = seq_len(length),
                                  bar = rnorm(length))

    temp_stock_info$baz <- paste("xxx",length)

    return(temp_stock_info)
  })

  ## Return an output
  output$my_table <- renderDataTable({
    stock_info()
  })
}

shinyApp(ui, server)

但是,如果您将中间对象l.out用于各种结束输出,那么将它作为自己的反应对象可能是有意义的。 然后,只要相关输入发生变化,我们就可以更新l.out ,然后使用该中间变量通过其他下游响应来级联更新。

此外,我们可以根据不影响l.out其他条件更新下游的反应对象,例如stock_info ,而l.out每次都重新运行l.out

library(shiny)

ui <- fluidPage(
  textInput('stock','stock',"GE"),
  sliderInput('length', 'length', min = 1, max = 100, value = 50),
  sliderInput('displayLength', 'displayLength', min = 1, max = 20, value = 5),
  dataTableOutput('my_table')
)

server <- function(input, output, session) {

  ## l.out will change with input$length and input$stock
  ## but NOT input$displayLength
  l.out <- reactive({
    data.frame(stock = input$stock,
               foo = rnorm(input$length),
               l.out_update_time = Sys.time())
  })

  ## stock_info will update whenever l.out changes or the displayLength changes. 
  ## l.out will NOT be updated if only input$displayLength changes
  stock_info <- reactive({
    tmp_stock_info <- head(x = l.out(), n = input$displayLength)
    tmp_stock_info$stock_info_update_time <- Sys.time()
    return(tmp_stock_info)
  })

  ## Return an output
  output$my_table <- renderDataTable({
    stock_info()
  })
}

shinyApp(ui, server)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM