R Shiny中如何结合selectInput与renderPlot(ggplot)实现年月筛选柱状图
解决Shiny中按年月筛选数据并绘制柱状图的问题
我来帮你搞定这个筛选功能,核心就是在绘图前根据用户选择的年月对数据集做过滤,下面是详细的修改步骤和完整代码:
1. 优化UI的年份选择器
你原来的selectInput用数字1-10对应2007-2016,后续还要做额外映射,不如直接把选项值设为实际年份,逻辑更直观:
selectInput("yil","1.Yıl Seçiniz", choices = c("2007"=2007, "2008"=2008, "2009"=2009, "2010"=2010, "2011"=2011, "2012"=2012, "2013"=2013, "2014"=2014, "2015"=2015, "2016"=2016))
这样input$yil直接返回用户选中的年份数值(比如2009),不用再转换。
2. 在Server中添加数据筛选逻辑
在renderPlot里,先通过dplyr::filter筛选出用户选择的年月对应的数据,再用筛选后的子集绘图:
output$bar <- renderPlot({ # 筛选目标年月的数据 filtered_data <- carsales %>% filter(Year == input$yil, Month == input$ay) # 绘制柱状图,额外优化了排序和标签可读性 ggplot(data = filtered_data, aes(x = reorder(Brand, -Quantity), y = Quantity, fill = Brand)) + geom_bar(stat = "identity") + labs(x = "Marka", y = "Satış Miktarı", title = paste0(input$yil, " Yılı ", input$ay, " Ayı Araç Satışları")) + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1), plot.title = element_text(hjust = 0.5)) })
这里加了几个实用优化:
- 用
reorder(Brand, -Quantity)让品牌按销量从高到低排序,图表更易读 - 动态生成标题,显示当前选中的年月
- 旋转x轴标签避免品牌名称重叠,标题居中更美观
完整修改后代码
ui.R
library(shiny) library(ggplot2) shinyUI(fluidPage( titlePanel(title=h4("Norvec Arac Satıs Verisi 2007-2016",align="center")), sidebarLayout( sidebarPanel( selectInput("yil","1.Yıl Seçiniz", choices = c("2007"=2007, "2008"=2008, "2009"=2009, "2010"=2010, "2011"=2011, "2012"=2012, "2013"=2013, "2014"=2014, "2015"=2015, "2016"=2016)), sliderInput("ay","2. Ay Seçiniz",min = 1,max = 12,value = 1,step = 1, animate = animationOptions(interval=800,loop = FALSE, playButton = "OYNAT", pauseButton = "DUR")) ), mainPanel( tabsetPanel(type="tab", tabPanel("Grafik",plotOutput("bar")) ) ) ) ))
server.R
library(shiny) library(ggplot2) library(dplyr) shinyServer(function(input,output){ output$bar <- renderPlot({ # 筛选用户选择的年月数据 filtered_data <- carsales %>% filter(Year == input$yil, Month == input$ay) # 绘制优化后的柱状图 ggplot(data = filtered_data, aes(x = reorder(Brand, -Quantity), y = Quantity, fill = Brand)) + geom_bar(stat = "identity") + labs(x = "Marka", y = "Satış Miktarı", title = paste0(input$yil, " Yılı ", input$ay, " Ayı Araç Satışları")) + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1), plot.title = element_text(hjust = 0.5)) }) })
注意事项
- 确保
carsales数据集已正确加载到Shiny环境(比如在server.R开头用read.csv("carsales.csv")或load("carsales.RData")) - 如果想保留原来的数字1-10对应年份,只需在server里加一行映射:
selected_year <- 2006 + input$yil,再把filter里的Year == input$yil改成Year == selected_year即可
内容的提问来源于stack exchange,提问作者redred10
相关产品推荐
相关产品推荐

