【问题标题】:Applying a function which takes in values and return the results from a data frame using Shiny应用一个函数,该函数接受值并使用 Shiny 从数据框中返回结果
【发布时间】:2020-10-18 22:02:13
【问题描述】:

我正在尝试开发一个应用程序,它会询问用户一些值,将这些值传递给函数并将结果输出到 Shiny 中的表格。

我的 R 代码如下:

someFunction <- function(S, K, type){
  
  # call option
  if(type=="C"){
    d1 <- S/K
    value <- S*pnorm(d1) - K*pnorm(d1)
    return(value)}
  
  # put option
  if(type=="P"){
    d1 <- S*K
    value <-  (K*pnorm(d1) - S*pnorm(d1))
    return(value)}
}


SInput <- 20
KInput <- 25
Seq <- seq(from = KInput - 1, to = KInput + 1, by = 0.25)

C <- someFunction(
  S = SInput,
  K = Seq,                                                  
  type = "C"
)

P <- someFunction(
  S = SInput,
  K = Seq,
  type = "P"
)

cbind(C, P)

这给了我:

              C    P
 [1,] -3.190686 4.00
 [2,] -3.379774 4.25
 [3,] -3.567795 4.50
 [4,] -3.754770 4.75
 [5,] -3.940723 5.00
 [6,] -4.125674 5.25
 [7,] -4.309646 5.50
 [8,] -4.492658 5.75
 [9,] -4.674731 6.00

我想使用 Shiny 将其输出为表格。我目前拥有的是:

library(shiny)
library(shinydashboard)

#######################################################################
############################### Functions #############################

someFunction <- function(S, K, type){
    
    # call option
    if(type=="C"){
        d1 <- S/K
        value <- S*pnorm(d1) - K*pnorm(d1)
        return(value)}
    
    # put option
    if(type=="P"){
        d1 <- S*K
        value <-  (K*pnorm(d1) - S*pnorm(d1))
        return(value)}
}


############################### Header ###############################
header <- dashboardHeader()

#######################################################################
############################### Sidebar ###############################
sidebar <- dashboardSidebar()

#######################################################################
############################### Body ##################################

body <- dashboardBody(
    fluidPage(
        numericInput("SInput", "Input S:", 10, min = 1, max = 100),
        numericInput("KInput", "Input K:", 10, min = 1, max = 100),
        verbatimTextOutput("S_K_Output")
    )
)

#######################################################################

ui <- dashboardPage(header, sidebar, body)

#######################################################################

server <- function(input, output) {
    
    output$S_K_Output <- observeEvent(
        
        input$Seq <- seq(from = input$KInput - 1, to = input$KInput + 1, by = 0.25),    # create a sequence going from K-1 to K+1

        input$C <- someFunction(
            S = input$SInput,
            K = input$Seq,                                                    # Apply this sequence to the function
            type = "C"
        ),
        
        input$P <- someFunction(
            S = input$SInput,
            K = input$Seq,
            type = "P"
        ),
        
        cbind(input$C, input$P)                                               # Extract the results and put side-by-side 
    )
}

我收到以下错误:

.getReactiveEnvironment()$currentContext() 中的错误:操作不 允许没有活动的反应上下文。 (你试图做某事 这只能从反应式表达式或观察者内部完成。)

我相信这是因为我试图通过 observeEvent() 传递数据。

我的问题是,如何允许用户输入值、应用函数并将结果显示在表格中?

【问题讨论】:

  • observeEvent 并不意味着返回一个值(它主要在副作用中运行)。也许你需要renderText 代替?
  • 当我申请 renderTablerenderText 时,我收到相同的错误消息。

标签: r shiny


【解决方案1】:

几个问题:

  1. observeEvent 通过副作用起作用(即,不要试图用任何返回值做某事);你需要的是renderText
  2. 您调用observeEvent 的方式是每个参数一个表达式,这不是它的工作方式:第一个参数应该是要监视/响应的反应组件的表达式,第二个是单个表达式当有事情发生时执行。如果它是复合的,那么您必须使用{...}(在其中一个或两个中)。您调用它的方式是 Seq &lt;- ... 是第一个参数,C &lt;- someFunction(...) 是它的第二个参数,依此类推。将所有这些放在 {...} 块中,并删除其中散布的逗号。
  3. 您正在尝试定义 new input 变量,这是不可能的。如果您需要一个临时变量,则定义一个不带input$ 的临时变量。如果您需要这个新的临时变量持续存在并在其他反应块中可用,那么您可以使用reactiveValreactiveValues。现在,从input$Seqinput$Cinput$P 中删除input$

这不会产生错误:

server <- function(input, output) {
    output$S_K_Output <- renderText({
        Seq <- seq(from = input$KInput - 1, to = input$KInput + 1, by = 0.25)    # create a sequence going from K-1 to K+1
        C <- someFunction(
            S = input$SInput,
            K = Seq,                                                    # Apply this sequence to the function
            type = "C"
        )
        P <- someFunction(
            S = input$SInput,
            K = Seq,
            type = "P"
        )
        cbind(C, P)                                               # Extract the results and put side-by-side 
    })
}

但是,这在任何意义上都不是“表格”,而是一长串字符。

有三种方法可以解决这个问题:

  1. 蛮力,不是首选/推荐。)捕获表格输出(如在 R 控制台中)并逐字粘贴。 (paste 部分是在文本中获取文字换行符\n。)

        output$S_K_Output <- renderText({
            # ... as above
            # cbind(C, P)
            paste(capture.output(cbind(C, P)), collapse="\n")
        })
    

  2. 也许您想要一个“真正的”HTML 表格?

    body <- dashboardBody(
        fluidPage(
            numericInput("SInput", "Input S:", 10, min = 1, max = 100),
            numericInput("KInput", "Input K:", 10, min = 1, max = 100),
            tableOutput("S_K_Output")
        )
    )
    server <- function(input, output) {
        output$S_K_Output <- renderTable({
          # ... as above
          cbind(C, P)
        })
    }
    

  3. 对于“更高级”的表,请考虑使用 DT 包。

【讨论】:

  • 完美,谢谢!我现在对 Shiny 有了更多的了解。再次感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多