英文:
Render plot based on plot type selection from user
问题
我正在开发一个R Shiny应用程序,用于与森林清查数据进行交互,我希望创建一个流程,用户可以从侧边栏界面中选择直方图或箱线图,并且Shiny会在主面板中生成所选的图。
以下是我目前的Shiny应用程序代码,其中包含一些生成的数据,输出了直方图和箱线图。我希望根据侧边栏面板中的用户输入只生成其中一个图:
library(shiny)
library(tidyverse)
library(ggplot2)
setwd(getwd())
# 准备 CFI 数据
cfi <- data.frame(total_BA = rnorm(200, 90, 20),
all_QMD = rnorm(200, 8, 1.2),
class1 = rep(c(1, 2, 3, 4), times = 50),
class2 = rep(c('D', 'S'), times = 100)) %>%
mutate_at(c('class1', 'class2'), as.factor)
##### 用户界面 #####
ui <- fluidPage(
titlePanel("CFI Viewer"),
sidebarLayout(
sidebarPanel("侧边栏面板标题",
selectInput("plot.type",
label = "选择图形类型",
choices = c('直方图', '箱线图'),
selected = "直方图"),
selectInput("var",
label = "选择要显示的变量",
choices = colnames(cfi[, c(1:2)]),
selected = "total_BA"),
sliderInput(inputId = "bins",
label = "选择直方图的柱数",
min = 5,
max = 50,
value = 15),
selectInput(inputId = "fac",
label = "选择箱线图的因子",
choices = c('class1', 'class2'),
selected = 'class1')
),
mainPanel("主面板标题",
fluidRow(plotOutput('hist')),
fluidRow(tableOutput('hist.sum')),
fluidRow(plotOutput('box')),
fluidRow(tableOutput('box.sum'))
)
)
)
##### 服务器 #####
server <- function(input, output, session) {
output$hist <- renderPlot({
ggplot(cfi, aes(x = get(input$var))) +
geom_histogram(bins = input$bins, color = "black", fill="darkgray")
})
output$hist.sum <- renderTable({
cfi %>%
summarize(Min = min(get(input$var), na.rm = TRUE),
Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
Median = median(get(input$var), na.rm = TRUE),
Mean = mean(get(input$var), na.rm = TRUE),
Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
Max = max(get(input$var), na.rm = TRUE),
NAs = sum(is.na(get(input$var)))
)
})
output$box <- renderPlot({
ggplot(cfi, aes(x = get(input$fac), y = get(input$var))) +
geom_boxplot(na.rm = TRUE) +
stat_summary(fun.y = mean, geom = "point", shape = 19, size = 2, na.rm = TRUE)
})
output$box.sum <- renderTable({
box.sum <- cfi %>%
group_by(get(input$fac)) %>%
summarize(Min = min(get(input$var), na.rm = TRUE),
Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
Median = median(get(input$var), na.rm = TRUE),
Mean = mean(get(input$var), na.rm = TRUE),
Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
Max = max(get(input$var), na.rm = TRUE),
N = n())
colnames(box.sum) <- c(input$fac, 'Min', 'Q1', 'Median', 'Mean', 'Q3', 'Max', 'N')
box.sum
})
}
##### 启动应用程序 #####
shinyApp(ui = ui, server = server)
英文:
I'm developing an R Shiny App to interact with forest inventory data and I want to create a process where a user selects either a Histogram or Box Plot from the sidebar interface and Shiny generates the selected plot in the main panel.
Below is my current code for the Shiny App with some generated data that outputs both the Histogram and Box plots. I would like for only one of these to be generated based on the user input in the sidebar panel:
library(shiny)
library(tidyverse)
library(ggplot2)
setwd(getwd())
# Prep CFI Data
cfi <- data.frame(total_BA = rnorm(200, 90, 20),
all_QMD = rnorm(200, 8, 1.2),
class1 = rep(c(1, 2, 3, 4), times = 50),
class2 = rep(c('D', 'S'), times = 100)) %>%
mutate_at(c('class1', 'class2'), as.factor)
##### User-Interface #####
ui <- fluidPage(
titlePanel("CFI Viewer"),
sidebarLayout(
sidebarPanel("sidebar panel title",
selectInput("plot.type",
label = "Select plot type",
choices = c('Histogram', 'Box Plot'),
selected = "Histogram"),
selectInput("var",
label = "Choose a variable to display",
choices = colnames(cfi[, c(1:2)]),
selected = "total_BA"),
sliderInput(inputId = "bins",
label = "Select # of bins for histogram",
min = 5,
max = 50,
value = 15),
selectInput(inputId = "fac",
label = "Choose a factor for box plot",
choices = c('class1', 'class2'),
selected = 'class1')
),
mainPanel("main panel title",
fluidRow(plotOutput('hist')),
fluidRow(tableOutput('hist.sum')),
fluidRow(plotOutput('box')),
fluidRow(tableOutput('box.sum'))
)
)
)
##### Server #####
server <- function(input, output, session) {
output$hist <- renderPlot({
ggplot(cfi, aes(x = get(input$var))) +
geom_histogram(bins = input$bins, color = "black", fill="darkgray")
})
output$hist.sum <- renderTable({
cfi %>%
summarize(Min = min(get(input$var), na.rm = TRUE),
Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
Median = median(get(input$var), na.rm = TRUE),
Mean = mean(get(input$var), na.rm = TRUE),
Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
Max = max(get(input$var), na.rm = TRUE),
NAs = sum(is.na(get(input$var)))
)
})
output$box <- renderPlot({
ggplot(cfi, aes(x = get(input$fac), y = get(input$var))) +
geom_boxplot(na.rm = TRUE) +
stat_summary(fun.y = mean, geom = "point", shape = 19, size = 2, na.rm = TRUE)
})
output$box.sum <- renderTable({
box.sum <- cfi %>%
group_by(get(input$fac)) %>%
summarize(Min = min(get(input$var), na.rm = TRUE),
Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
Median = median(get(input$var), na.rm = TRUE),
Mean = mean(get(input$var), na.rm = TRUE),
Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
Max = max(get(input$var), na.rm = TRUE),
N = n())
colnames(box.sum) <- c(input$fac, 'Min', 'Q1', 'Median', 'Mean', 'Q3', 'Max', 'N')
box.sum
})
}
##### Launch App #####
shinyApp(ui = ui, server = server)
答案1
得分: 1
需要使用 observeEvent
来观察并根据用户选择切换图表。我已经修改了您的代码,根据下拉选择在直方图和箱线图之间切换。
library(shiny)
library(tidyverse)
library(ggplot2)
setwd(getwd())
# 准备 CFI 数据
cfi <- data.frame(total_BA = rnorm(200, 90, 20),
all_QMD = rnorm(200, 8, 1.2),
class1 = rep(c(1, 2, 3, 4), times = 50),
class2 = rep(c('D', 'S'), times = 100)) %>%
mutate_at(c('class1', 'class2'), as.factor)
##### 用户界面 #####
ui <- fluidPage(
titlePanel("CFI Viewer"),
sidebarLayout(
sidebarPanel("侧边栏标题",
selectInput("plot.type",
label = "选择图表类型",
choices = c('直方图', '箱线图'),
selected = "直方图"),
selectInput("var",
label = "选择要显示的变量",
choices = colnames(cfi[, c(1:2)]),
selected = "total_BA"),
sliderInput(inputId = "bins",
label = "选择直方图的柱数",
min = 5,
max = 50,
value = 15),
selectInput(inputId = "fac",
label = "选择箱线图的因子",
choices = c('class1', 'class2'),
selected = 'class1')
),
mainPanel("主面板标题",
fluidRow(plotOutput('plot')),
fluidRow(tableOutput('data.sum'))
)
)
)
##### 服务器 #####
server <- function(input, output, session) {
observeEvent(input$plot.type,{
if(input$plot.type == '直方图'){
output$plot <- renderPlot({
ggplot(cfi, aes(x = get(input$var))) +
geom_histogram(bins = input$bins, color = "black", fill="darkgray")
})
output$data.sum <- renderTable({
cfi %>%
summarize(Min = min(get(input$var), na.rm = TRUE),
Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
Median = median(get(input$var), na.rm = TRUE),
Mean = mean(get(input$var), na.rm = TRUE),
Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
Max = max(get(input$var), na.rm = TRUE),
NAs = sum(is.na(get(input$var)))
)
})
} else if(input$plot.type == '箱线图'){
output$plot <- renderPlot({
ggplot(cfi, aes(x = get(input$fac), y = get(input$var))) +
geom_boxplot(na.rm = TRUE) +
stat_summary(fun.y = mean, geom = "point", shape = 19, size = 2, na.rm = TRUE)
})
output$data.sum <- renderTable({
box.sum <- cfi %>%
group_by(get(input$fac)) %>%
summarize(Min = min(get(input$var), na.rm = TRUE),
Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
Median = median(get(input$var), na.rm = TRUE),
Mean = mean(get(input$var), na.rm = TRUE),
Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
Max = max(get(input$var), na.rm = TRUE),
N = n())
colnames(box.sum) <- c(input$fac, 'Min', 'Q1', 'Median', 'Mean', 'Q3', 'Max', 'N')
box.sum
})
}
})
}
##### 启动应用程序 #####
shinyApp(ui = ui, server = server)
请注意,我将代码中的英文文本翻译为中文。
英文:
You need observeEvent
to observe and act based on the user selection to toggle between the plots. I have modified your code to switch between the histogram and box plot based on the dropdown selection.
library(shiny)
library(tidyverse)
library(ggplot2)
setwd(getwd())
# Prep CFI Data
cfi <- data.frame(total_BA = rnorm(200, 90, 20),
all_QMD = rnorm(200, 8, 1.2),
class1 = rep(c(1, 2, 3, 4), times = 50),
class2 = rep(c('D', 'S'), times = 100)) %>%
mutate_at(c('class1', 'class2'), as.factor)
##### User-Interface #####
ui <- fluidPage(
titlePanel("CFI Viewer"),
sidebarLayout(
sidebarPanel("sidebar panel title",
selectInput("plot.type",
label = "Select plot type",
choices = c('Histogram', 'Box Plot'),
selected = "Histogram"),
selectInput("var",
label = "Choose a variable to display",
choices = colnames(cfi[, c(1:2)]),
selected = "total_BA"),
sliderInput(inputId = "bins",
label = "Select # of bins for histogram",
min = 5,
max = 50,
value = 15),
selectInput(inputId = "fac",
label = "Choose a factor for box plot",
choices = c('class1', 'class2'),
selected = 'class1')
),
mainPanel("main panel title",
fluidRow(plotOutput('plot')),
fluidRow(tableOutput('data.sum'))
)
)
)
##### Server #####
server <- function(input, output, session) {
observeEvent(input$plot.type,{
if(input$plot.type == 'Histogram'){
output$plot <- renderPlot({
ggplot(cfi, aes(x = get(input$var))) +
geom_histogram(bins = input$bins, color = "black", fill="darkgray")
})
output$data.sum <- renderTable({
cfi %>%
summarize(Min = min(get(input$var), na.rm = TRUE),
Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
Median = median(get(input$var), na.rm = TRUE),
Mean = mean(get(input$var), na.rm = TRUE),
Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
Max = max(get(input$var), na.rm = TRUE),
NAs = sum(is.na(get(input$var)))
)
})
} else if(input$plot.type == 'Box Plot'){
output$plot <- renderPlot({
ggplot(cfi, aes(x = get(input$fac), y = get(input$var))) +
geom_boxplot(na.rm = TRUE) +
stat_summary(fun.y = mean, geom = "point", shape = 19, size = 2, na.rm = TRUE)
})
output$data.sum <- renderTable({
box.sum <- cfi %>%
group_by(get(input$fac)) %>%
summarize(Min = min(get(input$var), na.rm = TRUE),
Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
Median = median(get(input$var), na.rm = TRUE),
Mean = mean(get(input$var), na.rm = TRUE),
Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
Max = max(get(input$var), na.rm = TRUE),
N = n())
colnames(box.sum) <- c(input$fac, 'Min', 'Q1', 'Median', 'Mean', 'Q3', 'Max', 'N')
box.sum
})
}
})
}
##### Launch App #####
shinyApp(ui = ui, server = server)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论