Shiny上传数据集调用brushedPoints刷选数据报错如何解决
数据集示例
测试使用的经典mtcars数据集样例如下:
mpg cyl disp hp drat wt qsec vs am 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 3 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 21.4 6 258.0 110 3.08 3.215 19.44 1 0 5 18.7 8 360.0 175 3.15 3.440 17.02 0 0 6 18.1 6 225.0 105 2.76 3.460 20.22 1 0 7 14.3 8 360.0 245 3.21 3.570 15.84 0 0 8 24.4 4 146.7 62 3.69 3.190 20.00 1 0 9 22.8 4 140.8 95 3.92 3.150 22.90 1 0 10 19.2 6 167.6 123 3.92 3.440 18.30 1 0 11 17.8 6 167.6 123 3.92 3.440 18.90 1 0 12 16.4 8 275.8 180 3.07 4.070 17.40 0 0 13 17.3 8 275.8 180 3.07 3.730 17.60 0 0 14 15.2 8 275.8 180 3.07 3.780 18.00 0 0 15 10.4 8 472.0 205 2.93 5.250 17.98 0 0 16 10.4 8 460.0 215 3.00 5.424 17.82 0 0 17 14.7 8 440.0 230 3.23 5.345 17.42 0 0 18 32.4 4 78.7 66 4.08 2.200 19.47 1 1 19 30.4 4 75.7 52 4.93 1.615 18.52 1 1 20 33.9 4 71.1 65 4.22 1.835 19.90 1 1 21 21.5 4 120.1 97 3.70 2.465 20.01 1 0 22 15.5 8 318.0 150 2.76 3.520 16.87 0 0 23 15.2 8 304.0 150 3.15 3.435 17.30 0 0 24 13.3 8 350.0 245 3.73 3.840 15.41 0 0 25 19.2 8 400.0 175 3.08 3.845 17.05 0 0 26 27.3 4 79.0 66 4.08 1.935 18.90 1 1 27 26.0 4 120.3 91 4.43 2.140 16.70 0 1 28 30.4 4 95.1 113 3.77 1.513 16.90 1 1 29 15.8 8 351.0 264 4.22 3.170 14.50 0 1 30 19.7 6 145.0 175 3.62 2.770 15.50 0 1 31 15.0 8 301.0 335 3.54 3.570 14.60 0 1 32 21.4 4 121.0 109 4.11 2.780 18.60 1 1 gear carb 1 4 4 2 4 4 3 4 1 4 3 1 5 3 2 6 3 1 7 3 4 8 4 2 9 4 2 10 4 4 11 4 4 12 3 3 13 3 3 14 3 3 15 3 4 16 3 4 17 3 4 18 4 1 19 4 2 20 4 1 21 3 1 22 3 2 23 3 2 24 3 4 25 3 2 26 4 1 27 5 2 28 5 2 29 5 4 30 5 6 31 5 8 32 4 2
问题现象
在Shiny应用中实现散点图画刷框选功能时,使用内置预加载数据集功能正常,替换为用户上传的数据集后持续抛出如下错误:
Warning: Error in brushedPoints: brushedPoints: `xvar` ('.data[["the chosen variable"]]') not in names of input
原始复现代码如下:
library(shiny) library(ggplot2) library(datasets) ui <- shinyUI(fluidPage( titlePanel("Plot"), tabsetPanel( tabPanel("Upload File", titlePanel("Uploading Files"), sidebarLayout( sidebarPanel( fileInput('file1', 'Choose CSV File', accept=c('text/csv', 'text/comma-separated-values,text/plain', '.csv')), tags$br(), checkboxInput('header', 'Header', TRUE), radioButtons('sep', 'Separator', c(Comma=',', Semicolon=';', Tab='\t'), ','), radioButtons('quote', 'Quote', c(None='', 'Double Quote'='"', 'Single Quote'="'"), '"') ), mainPanel( tableOutput('contents') ) ) ), tabPanel("First Type", pageWithSidebar( headerPanel('My First Plot'), sidebarPanel( selectInput('xcol', 'X Variable', ""), selectInput('ycol', 'Y Variable', "", selected = "") ), mainPanel( plotOutput('MyPlot', click = "plot_click", hover = hoverOpts(id = "plot_hover", delayType = "throttle"), brush = brushOpts(id = "plot_brush")), hr(), tableOutput("plot_brushedpoints") ) ) ) ) ) ) server <- shinyServer(function(input, output, session) { data <- reactive({ req(input$file1) inFile <- input$file1 df <- read.csv(inFile$datapath, header = input$header, sep = input$sep, quote = input$quote) updateSelectInput(session, inputId = 'xcol', label = 'X Variable', choices = names(df), selected = names(df)) updateSelectInput(session, inputId = 'ycol', label = 'Y Variable', choices = names(df), selected = names(df)[2]) return(df) }) output$contents <- renderTable({ data() }) output$MyPlot <- renderPlot({ graph <- ggplot(data(), aes(.data[[input$xcol]], .data[[input$ycol]])) + geom_point(position='jitter') graph }) output$plot_brushedpoints <- renderTable({ df<- data() res <- brushedPoints(df, input$plot_brush, xvar = df$xcol, yvar = df$ycol, panelvar1 = NULL, panelvar2 = NULL, allRows = FALSE ) if (nrow(res) == 0|is.null(res)) return(NULL) res }) }) shinyApp(ui, server)
错误原因
brushedPoints 函数的 xvar、yvar 参数需要传入和数据框列名完全匹配的字符串,原代码存在两个核心错误:
- 错误使用
df$xcol、df$ycol取值:xcol/ycol是input对象的属性,不是上传数据框df的列,该写法返回值为NULL - 误用ggplot专有语法:
.data[[input$xcol]]是ggplot的代词语法,brushedPoints无法识别,会直接把整段语法字符串当列名去匹配,自然找不到对应列 - ggplot绘图时未给
aes()里的x、y映射显式命名,绘图对象不会记录原始列名,brushedPoints无法自动匹配坐标轴对应的列。
修复方案
修改两处核心逻辑即可:
- ggplot绘图的
aes映射中,给x、y显式命名,保证绘图对象能正确记录坐标轴对应的原始列名 brushedPoints的xvar、yvar直接传入input$xcol、input$ycol,这两个值本身就是用户选择的列名字符串,可直接和数据框列名匹配,不需要加df$或.data[[]]包裹。
修正后完整可运行代码:
library(shiny) library(ggplot2) ui <- shinyUI(fluidPage( titlePanel("Plot"), tabsetPanel( tabPanel("Upload File", titlePanel("Uploading Files"), sidebarLayout( sidebarPanel( fileInput('file1', 'Choose CSV File', accept=c('text/csv', 'text/comma-separated-values,text/plain', '.csv')), tags$br(), checkboxInput('header', 'Header', TRUE), radioButtons('sep', 'Separator', c(Comma=',', Semicolon=';', Tab='\t'), ','), radioButtons('quote', 'Quote', c(None='', 'Double Quote'='"', 'Single Quote'="'"), '"') ), mainPanel( tableOutput('contents') ) ) ), tabPanel("First Type", pageWithSidebar( headerPanel('My First Plot'), sidebarPanel( selectInput('xcol', 'X Variable', ""), selectInput('ycol', 'Y Variable', "", selected = "") ), mainPanel( plotOutput('MyPlot', click = "plot_click", hover = hoverOpts(id = "plot_hover", delayType = "throttle"), brush = brushOpts(id = "plot_brush")), hr(), tableOutput("plot_brushedpoints") ) ) ) ) ) ) server <- shinyServer(function(input, output, session) { data <- reactive({ req(input$file1) inFile <- input$file1 df <- read.csv(inFile$datapath, header = input$header, sep = input$sep, quote = input$quote) updateSelectInput(session, inputId = 'xcol', label = 'X Variable', choices = names(df), selected = names(df)[1]) updateSelectInput(session, inputId = 'ycol', label = 'Y Variable', choices = names(df), selected = names(df)[2]) return(df) }) output$contents <- renderTable({ data() }) output$MyPlot <- renderPlot({ # 显式指定x、y映射名称 graph <- ggplot(data(), aes(x = .data[[input$xcol]], y = .data[[input$ycol]])) + geom_point(position='jitter') graph }) output$plot_brushedpoints <- renderTable({ req(input$plot_brush) df<- data() res <- brushedPoints(df, input$plot_brush, # 直接传入input存储的列名字符串 xvar = input$xcol, yvar = input$ycol, allRows = FALSE ) if (nrow(res) == 0) return(NULL) res }) }) shinyApp(ui, server)
内容的提问来源于stack exchange,提问作者EnriqueGG
相关产品推荐
相关产品推荐

