You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R Shiny应用中ggplot aes_string无法识别X/Y轴及日期显示异常

解决你的R Shiny应用两个问题

我来帮你逐个排查并解决这两个头疼的问题:

问题1:ggplot提示缺少x、y美学参数

你遇到的geom_point requires the following missing aesthetics: x, y错误,主要有两个核心原因:

  • 未定义choices变量:你的selectInput里用了choices = c(choices),但这个choices变量根本没提前定义!应该把它设置为数据集的列名(按需排除日期列),比如在UI定义前加一行:

    choices <- colnames(data4)[!colnames(data4) %in% "Deployment.Month"]
    

    这样下拉框就会自动显示除日期外的所有列选项。

  • aes_string的使用和参数位置错误:你把colour='red'放在了ggplot()的参数里,但这个是点的样式参数,应该移到geom_point()里;另外要确保input$x和input$y对应的列确实存在于筛选后的数据集里,且是适合做散点图的数值类型。修改后的renderPlot代码:

    output$scatterplot <- renderPlot({
      # 确保所有必要输入都已加载
      req(input$date, input$x, input$y)
      projects_selected_date <- data4 %>%
        filter(Deployment.Month >= input$date[1] & Deployment.Month <= input$date[2])
      
      # 避免空数据导致报错
      validate(need(nrow(projects_selected_date) > 0, "没有符合日期范围的数据哦"))
      
      ggplot(projects_selected_date, aes_string(x = input$x, y = input$y)) +
        geom_point(colour = 'red') # 把颜色参数放到geom层
    })
    

问题2:表格中日期显示为数字

R中的Date类型本质是整数(从1970-01-01开始的天数),renderTable默认会把它转换成数字显示。给你两种解决方法:

方法1:将日期列转为字符格式(快速解决)

在输出表格前,把Deployment.Month转成可读的字符格式:

output$table <- renderTable({
  req(input$date)
  projects_selected_date <- data4 %>%
    filter(Deployment.Month >= input$date[1] & Deployment.Month <= input$date[2]) %>%
    mutate(Deployment.Month = as.character(Deployment.Month)) # 转成人类可读的日期字符串
  projects_selected_date
})

方法2:使用DT包的renderDataTable(推荐)

DT包会自动识别Date类型并正确显示,还自带排序、搜索等实用功能。先安装加载DT:

install.packages("DT")
library(DT)

然后修改UI和Server:

  • UI里把tableOutput("table")改成DTOutput("table")
  • Server里替换成:
    output$table <- renderDT({
      req(input$date)
      projects_selected_date <- data4 %>%
        filter(Deployment.Month >= input$date[1] & Deployment.Month <= input$date[2])
      projects_selected_date
    })
    

完整修正后的代码示例

把上述修改整合后,完整代码如下(包含两种表格输出方式,按需注释切换):

library(shiny)
library(dplyr)
library(ggplot2)
library(DT) # 用DT的话需要加载

# 先处理你的原始数据
data2$Deployment.Month <- as.Date(data2$Deployment.Month, format = "%d-%m-%Y")
# 添加na.rm避免NA值影响日期范围计算
min_date <- min(data2$Deployment.Month, na.rm = TRUE)
max_date <- max(data2$Deployment.Month, na.rm = TRUE)
data3 <- as.data.frame(data2)
data4 <- na.omit(data3)

# 定义下拉框选项
choices <- colnames(data4)[!colnames(data4) %in% "Deployment.Month"]

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "x", label = "Variable 1", 
                  choices = choices, selected = "Project.Id"),
      selectInput(inputId = "y", label = "Variable 2", choices = choices),
      dateRangeInput(inputId = "date", label = "Select dates:", 
                     start = "2013-01-01", end = "2017-12-31", 
                     startview = "year", min = min_date, max = max_date)
    ),
    mainPanel(
      plotOutput(outputId = "scatterplot"),
      DTOutput("table") # 用DT的话用这个,否则换成tableOutput("table")
    )
  )
)

server <- function(input, output){
  output$scatterplot <- renderPlot({
    req(input$date, input$x, input$y)
    projects_selected_date <- data4 %>%
      filter(Deployment.Month >= input$date[1] & Deployment.Month <= input$date[2])
    
    validate(need(nrow(projects_selected_date) > 0, "没有符合日期范围的数据哦"))
    
    ggplot(projects_selected_date, aes_string(x = input$x, y = input$y)) +
      geom_point(colour = 'red')
  })
  
  # 方法1:用renderTable的写法(需要把UI里的DTOutput改回tableOutput)
  # output$table <- renderTable({
  #   req(input$date)
  #   projects_selected_date <- data4 %>%
  #     filter(Deployment.Month >= input$date[1] & Deployment.Month <= input$date[2]) %>%
  #     mutate(Deployment.Month = as.character(Deployment.Month))
  #   projects_selected_date
  # })
  
  # 方法2:用DT的写法
  output$table <- renderDT({
    req(input$date)
    projects_selected_date <- data4 %>%
      filter(Deployment.Month >= input$date[1] & Deployment.Month <= input$date[2])
    projects_selected_date
  })
}

shinyApp(ui = ui, server = server)

最后提两个小细节:

  • 计算min_date和max_date时加na.rm = TRUE,避免原始数据里的NA值导致报错;
  • dateRangeInput里的min和max参数不用再转as.Date,因为min_date已经是Date类型了。

内容的提问来源于stack exchange,提问作者Nitesh Rohilla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:27:47