[英]Reactive ggplot with reactive data frame in Shiny
This is a follow on post to one I made here .这是我在此处制作的帖子的后续内容。 The original question required the user to input some values into some text boxes/numeric boxes compute some function and then display the result in a data frame.
原始问题要求用户在一些文本框/数字框中输入一些值,计算一些 function,然后在数据框中显示结果。 It can be computed using the following R code (which also includes the
ggplot2
plot I would also like to add).它可以使用以下 R 代码(还包括
ggplot2
plot 我还想添加)来计算。
R Code: 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"
)
df <- data.frame(C, P, Seq) # create the data frame for the ggplot and Shiny output
df %>% # plot that data frame
ggplot(aes(x = Seq)) +
geom_line(aes(y = C)) +
geom_line(aes(y = P))
I want to create the same ggplot
- reactive plot in Shiny.我想在 Shiny 中创建相同的
ggplot
- 反应式 plot。 The Shiny code I have is the following.我拥有的 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),
tableOutput("S_K_Output")
)
)
#######################################################################
ui <- dashboardPage(header, sidebar, body)
#######################################################################
server <- function(input, output) {
output$S_K_Output <- renderTable({
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"
)
data.frame(C, P, Seq) # Extract the results and put side-by-side
})
}
shinyApp(ui, server)
The above Shiny code works for producing the table but I also want to include the plot.上面的 Shiny 代码适用于生成表格,但我还想包括 plot。 I am finding it difficult since the above code outputs the results into a
renderTable({})
function (ie returning a HTML table and simply adding the ggplot
code doesn't work.)我发现这很困难,因为上面的代码将结果输出到
renderTable({})
function (即返回 HTML 表并简单地添加ggplot
代码不起作用。)
I have tried renderPlot
and pasting all the above code again from renderTable
into the same function but I don't want to repeat unnecessary calculations.我已经尝试
renderPlot
并将上述所有代码再次从renderTable
粘贴到同一个 function 但我不想重复不必要的计算。 So my question is how can I export the data.frame(C, P, Seq)
into a ggplot2
graphic from two different renderTable
and renderPlot
?所以我的问题是如何将
data.frame(C, P, Seq)
从两个不同的renderTable
和renderPlot
导出到ggplot2
图形中? I can add the tablePlot
just under the tableOutput
in the fluidPage
part of the code but I am not able to get results.我可以在代码的
fluidPage
部分的tablePlot
下添加tableOutput
,但我无法获得结果。
Start thinking about dependency and removing redundancy.开始考虑依赖和消除冗余。 That is, if you are creating data of some sort and you even think that it will be used by more than one "thing", then break it out into "reactive data", and then depend on it in multiple locations.
也就是说,如果您正在创建某种数据,并且您甚至认为它将被多个“事物”使用,那么将其分解为“反应性数据”,然后在多个位置依赖它。
Oh, and if you want to show a plot, you need to use plotOutput
.哦,如果你想显示 plot,你需要使用
plotOutput
。
Changes from your previous code:与您之前的代码相比的更改:
plotOutput
;plotOutput
;renderTable
into a reactive
block that just calculates data , it does nothing to consider how to show or filter it;renderTable
中的代码转换为只计算数据的reactive
块,它不考虑如何显示或过滤它;renderTable
to deal with the data as created in the previously-mentioned block;renderTable
来处理前面提到的块中创建的数据;renderPlot
(paired with plotOutput
);renderPlot
(与plotOutput
配对); and finallyreq(mydata())
to the plot output, so that if the data is empty or NULL
(for whatever reason), then the plotting code will not fire.req(mydata())
添加到 plot output,这样如果数据为空或NULL
(无论出于何种原因),则绘图代码将不会触发。 See ?req
if you have questions about this, or its companion functions validate
and need
.?req
,或者它的配套函数validate
和need
。 Note that when using reactive data, you must call it like a function.请注意,当使用响应式数据时,您必须像 function 一样调用它。 So the
mydata
reactive data block makes its data available to other reactive components when called as mydata()
.因此,当调用
mydata()
时, mydata
响应式数据块使其数据可用于其他响应式组件。 Do not try to "view" mydata
(without the parens), it does nothing for you.不要试图“查看”
mydata
(没有括号),它对你没有任何作用。
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),
tableOutput("S_K_Output"),
plotOutput("Plot_Output")
)
)
#######################################################################
ui <- dashboardPage(header, sidebar, body)
#######################################################################
server <- function(input, output) {
mydata <- reactive({
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"
)
data.frame(C, P, Seq) # Extract the results and put side-by-side
})
output$S_K_Output <- renderTable({ mydata() })
output$Plot_Output <- renderPlot({
req(mydata())
# plot that data frame
ggplot(mydata(), aes(x = Seq)) +
geom_line(aes(y = C)) +
geom_line(aes(y = P))
})
}
shinyApp(ui, server)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.