简体   繁体   English

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

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

within the server for my shinyApp, I created a dataframe based on the inputs. 在我的shinyApp服务器中,我根据输入创建了一个数据帧。 However, I want to add a new column that utilizes two of the columns of that dataframe. 但是,我想添加一个新列,该列使用该数据帧的两列。

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])
    }
  })

I have tried it like this, and it works up until I try to create stock_info()$return, where I keep getting the error that NULL left assignment. 我已经尝试过这样的做法,直到我尝试创建stock_info()$ return,然后我一直得到NULL留下赋值的错误。 Any tips? 有小费吗?

I'm not familiar with the BatchGetSymbols package, but the concepts in the example below should be applicable for your use case as well. 我不熟悉BatchGetSymbols包,但下面示例中的概念也适用于您的用例。

First things first, for lack of an elegant way to say this, I'm pretty sure the expression... 首先,由于缺乏优雅的说法,我很确定表达方式......

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

...just isn't really how shiny reactive objects and the associated syntax work. ......实际上并不是反应性对象和相关语法的shiny

It looks like you could simplify your code a lot by condensing a bunch of your intermediate steps into a single expression. 看起来你可以通过将一堆中间步骤压缩成单个表达式来大大简化代码。 If you only have one set of reactive data you will use in all of your outputs, this might be a more straight forward approach. 如果您只有一组反应数据,您将在所有输出中使用,这可能是一种更直接的方法。

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)

However, if you are using the intermediate object l.out for a variety of end outputs, it might make sense to make it a reactive object of it's own. 但是,如果您将中间对象l.out用于各种结束输出,那么将它作为自己的反应对象可能是有意义的。 Then, we can update l.out whenever a relevant input changes, and then use that intermediate variable to cascade updates through the other downstream reactives. 然后,只要相关输入发生变化,我们就可以更新l.out ,然后使用该中间变量通过其他下游响应来级联更新。

In addition, we can update downstream reactive objects like stock_info based on other conditions that don't affect l.out without re-running l.out every time. 此外,我们可以根据不影响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