Flexdashboard - 模块化 rCharts 代码
Flexdashboard - Modularise rCharts code
我正在尝试将仪表板的一些代码分解为模块。我在使用此 rCharts
代码时遇到问题。我可以 运行 它作为一个应用程序,但理想情况下我想把它分成 UI
和 server
函数,这样我就可以把它们放在一个包里。
下面的代码显示了应用程序中的工作代码和作为模块的损坏代码。谁能指出我做错了什么?
谢谢
---
title: "Example"
output:
flexdashboard::flex_dashboard:
runtime: shiny
---
```{r setup, include=FALSE}
library(flexdashboard)
library(shiny)
library(rCharts)
X <- data.frame(Var1 = rep(1:10, 3),
Var2 = rep(c("control", "treatment1", "treatment2"), each = 10),
Freq = abs(rnorm(30, 0, 1))
)
```
Column {data-width=650}
-----------------------------------------------------------------------
### Broken Code as Module
```{r}
ui2 = function(id) {
ns = NS(id)
mainPanel(plotOutput("plot1", height = "100%"),
showOutput(ns("histogram"), "nvd3"))
}
server2 = function(input, output, session) {
output$histogram <- renderChart2({
n2 <- nPlot(Freq ~ Var1, group = 'Var2', data = X, type = 'multiBarChart')
n2$set(width = session$clientData$output_plot1_width)
n2
})
}
ui2("example")
callModule(server2, "example")
```
Column {data-width=350}
-----------------------------------------------------------------------
### Working Code as App
```{r}
shinyApp(
ui = mainPanel(
plotOutput("plot2", height = "100%"),
showOutput("histogram", "nvd3")
),
server = function(input, output, session) {
output$histogram <- renderChart2({
n2 <- nPlot(Freq ~ Var1, group = 'Var2', data = X, type = 'multiBarChart')
n2$set(width = session$clientData$output_plot2_width)
n2
})
}
)
```
### Template
```{r}
```
更新以回应@HubertL 的回复
下面的代码,当附加到上面的主要 body 时,说明了 flexdashboard
可以 运行 shiny
应用程序作为独立功能的方式(注意 runtime: shiny
在 header).
这里的独立函数可以存放在一个库中随意调用,不需要shinyApp
包装。
澄清一下,我要问的问题是如何将 rCharts
图调用为一系列独立的 UI 和服务器函数,就像我可以用普通的 plots
,或者如果这不可能,为什么不呢?
Stand Alone Example
======================================================================
Inputs{.sidebar}
-----------------------------------------------------------------------
```{r}
## UI for choosing species
iris_plotUI = function(id) {
ns = NS(id)
# User choices for line
list_species = list(
"Setosa" = "setosa",
"Versicolor" = "versicolor",
"Virginica" = "virginica"
)
flowLayout(
# input: Tube line selection
selectInput(
ns("type"),
label = h3("Select Species:"),
choices = list_species,
selected = "setosa"
)
)
}
# server module
iris_plot = function(input, output, session) {
library(MASS)
library(data.table)
dt = data.table::copy(iris)
data.table::setDT(dt)
iris_filtered = reactive({
dt[Species == input$type]
})
output$scatter = renderPlot({
plot(iris_filtered()$Petal.Width,
iris_filtered()$Petal.Length)
})
}
# plotting module
iris_plotOutput = function(id) {
ns = NS(id)
plotOutput(ns("scatter"))
}
## call inputs in the sidebar
iris_plotUI("ns_iris")
```
Column
-----------------------------------------------------------------------
```{r}
## all server module and plot (plot in main panel)
callModule(iris_plot, "ns_iris")
iris_plotOutput("ns_iris")
```
WRT 命名约定,这已在博客 post 的评论中阐明。留言:
It's a bit unclear to me, do the suffixes UI, Input, Output affect behavior or is that a suggested naming convention?
其中一位作者已回答:
Just a suggested naming convention, they don't affect anything.
您的代码有 2 个小问题:
1。模块函数的命名不符合the documentation you are referring to
A module’s UI function should be given a name that is suffixed with
Input
, Output
, or UI
和
Module server functions should be named like their corresponding
module UI functions, but without the Input/Output/UI
suffix
这里我把它们重命名为myUI()
和my()
:
myUI = function(id) {
ns = NS(id)
mainPanel(plotOutput("plot1", height = "100%"),
showOutput(ns("histogram"), "nvd3"))
}
my = function(input, output, session) {
output$histogram <- renderChart2({
n2 <- nPlot(Freq ~ Var1, group = 'Var2', data = X, type = 'multiBarChart')
n2$set(width = session$clientData$output_plot1_width)
n2
})
}
2。调用模块服务器功能的方式就像它们是独立的一样
相反,它们必须由 ui()
和 server()
调用,它们本身由 shinyApp()
调用。
ui <- fluidPage(
myUI("example")
)
server <- function(input, output, session) {
callModule(my, "example")
}
shinyApp(ui, server)
我使用 htmlwidget
而不是 rCharts
来解决这个问题。仍然不确定为什么 rCharts
不让我在 htmlwigdets
允许的情况下将函数称为独立的,但是由于 htmlwidgets
似乎概括了 rCharts
,这对我来说解决了这个问题.
我正在尝试将仪表板的一些代码分解为模块。我在使用此 rCharts
代码时遇到问题。我可以 运行 它作为一个应用程序,但理想情况下我想把它分成 UI
和 server
函数,这样我就可以把它们放在一个包里。
下面的代码显示了应用程序中的工作代码和作为模块的损坏代码。谁能指出我做错了什么?
谢谢
---
title: "Example"
output:
flexdashboard::flex_dashboard:
runtime: shiny
---
```{r setup, include=FALSE}
library(flexdashboard)
library(shiny)
library(rCharts)
X <- data.frame(Var1 = rep(1:10, 3),
Var2 = rep(c("control", "treatment1", "treatment2"), each = 10),
Freq = abs(rnorm(30, 0, 1))
)
```
Column {data-width=650}
-----------------------------------------------------------------------
### Broken Code as Module
```{r}
ui2 = function(id) {
ns = NS(id)
mainPanel(plotOutput("plot1", height = "100%"),
showOutput(ns("histogram"), "nvd3"))
}
server2 = function(input, output, session) {
output$histogram <- renderChart2({
n2 <- nPlot(Freq ~ Var1, group = 'Var2', data = X, type = 'multiBarChart')
n2$set(width = session$clientData$output_plot1_width)
n2
})
}
ui2("example")
callModule(server2, "example")
```
Column {data-width=350}
-----------------------------------------------------------------------
### Working Code as App
```{r}
shinyApp(
ui = mainPanel(
plotOutput("plot2", height = "100%"),
showOutput("histogram", "nvd3")
),
server = function(input, output, session) {
output$histogram <- renderChart2({
n2 <- nPlot(Freq ~ Var1, group = 'Var2', data = X, type = 'multiBarChart')
n2$set(width = session$clientData$output_plot2_width)
n2
})
}
)
```
### Template
```{r}
```
更新以回应@HubertL 的回复
下面的代码,当附加到上面的主要 body 时,说明了 flexdashboard
可以 运行 shiny
应用程序作为独立功能的方式(注意 runtime: shiny
在 header).
这里的独立函数可以存放在一个库中随意调用,不需要shinyApp
包装。
澄清一下,我要问的问题是如何将 rCharts
图调用为一系列独立的 UI 和服务器函数,就像我可以用普通的 plots
,或者如果这不可能,为什么不呢?
Stand Alone Example
======================================================================
Inputs{.sidebar}
-----------------------------------------------------------------------
```{r}
## UI for choosing species
iris_plotUI = function(id) {
ns = NS(id)
# User choices for line
list_species = list(
"Setosa" = "setosa",
"Versicolor" = "versicolor",
"Virginica" = "virginica"
)
flowLayout(
# input: Tube line selection
selectInput(
ns("type"),
label = h3("Select Species:"),
choices = list_species,
selected = "setosa"
)
)
}
# server module
iris_plot = function(input, output, session) {
library(MASS)
library(data.table)
dt = data.table::copy(iris)
data.table::setDT(dt)
iris_filtered = reactive({
dt[Species == input$type]
})
output$scatter = renderPlot({
plot(iris_filtered()$Petal.Width,
iris_filtered()$Petal.Length)
})
}
# plotting module
iris_plotOutput = function(id) {
ns = NS(id)
plotOutput(ns("scatter"))
}
## call inputs in the sidebar
iris_plotUI("ns_iris")
```
Column
-----------------------------------------------------------------------
```{r}
## all server module and plot (plot in main panel)
callModule(iris_plot, "ns_iris")
iris_plotOutput("ns_iris")
```
WRT 命名约定,这已在博客 post 的评论中阐明。留言:
It's a bit unclear to me, do the suffixes UI, Input, Output affect behavior or is that a suggested naming convention?
其中一位作者已回答:
Just a suggested naming convention, they don't affect anything.
您的代码有 2 个小问题:
1。模块函数的命名不符合the documentation you are referring to
A module’s UI function should be given a name that is suffixed with
Input
,Output
, orUI
和
Module server functions should be named like their corresponding module UI functions, but without the
Input/Output/UI
suffix
这里我把它们重命名为myUI()
和my()
:
myUI = function(id) {
ns = NS(id)
mainPanel(plotOutput("plot1", height = "100%"),
showOutput(ns("histogram"), "nvd3"))
}
my = function(input, output, session) {
output$histogram <- renderChart2({
n2 <- nPlot(Freq ~ Var1, group = 'Var2', data = X, type = 'multiBarChart')
n2$set(width = session$clientData$output_plot1_width)
n2
})
}
2。调用模块服务器功能的方式就像它们是独立的一样
相反,它们必须由 ui()
和 server()
调用,它们本身由 shinyApp()
调用。
ui <- fluidPage(
myUI("example")
)
server <- function(input, output, session) {
callModule(my, "example")
}
shinyApp(ui, server)
我使用 htmlwidget
而不是 rCharts
来解决这个问题。仍然不确定为什么 rCharts
不让我在 htmlwigdets
允许的情况下将函数称为独立的,但是由于 htmlwidgets
似乎概括了 rCharts
,这对我来说解决了这个问题.