[英]Dynamically change plots based on user input in Shiny
我正在嘗試創建一個閃亮的應用程序,該應用程序根據用戶對已加載數據框的子集的選擇來生成圖。 例如,我有以下數據集:
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
值,我希望Shiny為每個grp
值生成圖表。 因此,如果用戶選擇“ X”,則將生成4個圖。 如果選擇“ Y”,則為3;如果選擇“ Z”,則為3。
我還想指定如何根據grp
的值生成每個圖表。 因此,如果grp
是A,D或EI,則希望它生成折線圖,否則應生成散點圖(僅當該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)
在底部可以找到可復制的示例。
一些提示:
1)使用反應式上下文:
在服務器代碼底部的for循環中,您正在使用反應性變量rv
,因此您將必須在反應性內容中運行代碼。 因此將其包裝在observe()
。
2)創建輸出列表:
如果我沒記錯的話,您在此答案中使用了一些代碼:使用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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.