我正在尝试创建一个闪亮的应用程序,该应用程序根据用户对已加载数据框的子集的选择来生成绘图。例如,我有以下数据集:
library(shiny)
library(data.table)
df <- rbind(
data.table( cat = rep('X', 40), grp = rep(LETTERS[1:4], each=10), x = rep(1:10, times=4), y = rnorm(40) ),
data.table( cat = rep('Y', 30), grp = rep(LETTERS[1:3], each=10), x = rep(1:10, times=3), y = rnorm(30) ),
data.table( cat = rep('Z', 20), grp = rep(LETTERS[4:6], each=10), x = rep(1:10, times=2), y = rnorm(20) )
)
基于用户在UI中选择的cat
的值,我希望发亮为grp
的每个值生成图表。因此,如果用户选择“ X”,则将生成4个图。如果选择“ Y”,则为3;如果选择“ Z”,则为3。
我还想指定如何基于grp
的值生成每个图表。因此,如果grp
是A,D或E,我希望它产生一个线图,否则它将产生一个散点图(仅当该grp
当然具有那个值时)。
以下是我(破损的)闪亮应用程序的代码:
server <- function(input, output) {
rv <- reactiveValues(
i = NULL,
df = NULL
)
observe({ rv$i <- input$i })
observe({ rv$df <- df[cat == rv$i] })
output$test <- renderUI({
plotList <- lapply( LETTERS[1:6], function(x) plotOutput(x) )
do.call( tagList, unlist(plotList, recursive=FALSE))
})
for(i in LETTERS[1:6]){
local({
my_i <- i
output[[my_i]] <- renderPlot({
if( my_i %in% c('A','D','E')) {
with(rv$df[grp == my_i], plot(x,y, type='l'))
} else {
with(rv$df[grp == my_i], plot(x,y))
}
})
})
}
}
ui <- fluidPage(
titlePanel('Title'),
sidebarLayout(
sidebarPanel(
helpText('Select the Category you would like to view.'),
selectInput('i', 'Category', c('X','Y','Z'), selectize=TRUE)
),
mainPanel(
uiOutput('test')
)
)
)
shinyApp(ui, server)
答案 0 :(得分:3)
在底部可以找到一个可复制的示例。
一些提示:
1)使用反应性上下文:
在服务器代码底部的for循环中,您正在使用反应性变量rv
,因此您将必须在反应性内容中运行代码。因此,将其包装在observe()
中。
2)创建输出列表:
如果我没记错的话,您在此答案中使用了一些代码:dynamically add plots to web page using shiny。
这是一个很好的起点。对于标签列表而言,简化为:
output$test <- renderUI({
lapply(unique(rv$df$grp), plotOutput)
})
您也可以添加tagList()
,但是这里没有必要,...
3)更正示例数据:
您可能要更新df变量:
data.table(cat = rep('Z', 20), grp = rep(LETTERS[4:6], each=10),
x = rep(1:10, times=2), y = rnorm(20) )
这里有三个字母,因此您可以将其更改为LETTERS[5:6]
或更新其他数字。
完整的示例:
library(shiny)
library(data.table)
df <- rbind(
data.table( cat = rep('X', 40), grp = rep(LETTERS[1:4], each=10), x = rep(1:10, times=4), y = rnorm(40) ),
data.table( cat = rep('Y', 30), grp = rep(LETTERS[1:3], each=10), x = rep(1:10, times=3), y = rnorm(30) ),
data.table( cat = rep('Z', 30), grp = rep(LETTERS[4:6], each=10), x = rep(1:10, times=3), y = rnorm(30) )
)
server <- function(input, output) {
rv <- reactiveValues(
i = NULL,
df = NULL
)
observe({ rv$i <- input$i })
observe({ rv$df <- df[cat == rv$i] })
observe({
for(letter in unique(rv$df$grp)){
local({
let <- letter
output[[let]] <- renderPlot({
if( let %in% c('A','D','E')) {
with(rv$df[grp == let], plot(x, y, type='l'))
} else {
with(rv$df[grp == let], plot(x,y))
}
})
})
}
})
output$test <- renderUI({
lapply(unique(rv$df$grp), plotOutput)
})
}
ui <- fluidPage(
titlePanel('Title'),
sidebarLayout(
sidebarPanel(
helpText('Select the Category you would like to view.'),
selectInput('i', 'Category', c('X','Y','Z'), selectize=TRUE)
),
mainPanel(
uiOutput('test')
)
)
)
shinyApp(ui, server)