R Shiny函数循环绘图故障:selectInput传参报字符串转符号错误
问题解决:Shiny中ggplot自定义函数传字符串列名报错
问题
自定义散点图函数在R Markdown中直接传列名(如Petal.Length)能正常运行,在Shiny中直接传列名也能工作,但通过selectInput传递字符串格式的列名时,出现Only strings can be converted to symbols错误,尝试改用aes_string未解决问题。
错误原因
函数中使用ensym()处理参数,该函数仅能将**裸变量名(符号)**转换为符号对象,而Shiny的selectInput返回的是字符串类型的列名,导致转换失败。此外,原函数中部分数据引用和全局赋值的写法也存在优化空间。
修复方案
- 将参数转换从
ensym()改为sym(),sym()专门用于将字符串转换为符号对象,兼容Shiny的字符串输入。 - 修正相关系数计算时的数据引用方式,使用
pull()替代字符串索引,更符合tidyverse规范。 - 移除不必要的全局赋值
corr<<-corr,避免污染全局环境。
修改后的完整代码
library(shiny) library(tidyverse) library(scales) library(ggpubr) scatter_fun <- function(data, xval, yval) { # 将字符串转为符号 xval <- sym(xval) yval <- sym(yval) plot_list = list() corr = list() for (i in 0:3) { data2 <- data %>% mutate(x1 = lag(!!xval, i), y1 = !!yval) p <- ggplot(data2, aes(x1, y1)) + geom_point(size = 3, color = "#6724C6") + theme( axis.line.x.bottom = element_line("black"), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line.y.left = element_line("black"), panel.grid.major.x = element_blank(), legend.title = element_blank() ) + ylab(quo_name(yval)) + xlab(quo_name(xval)) + scale_y_continuous(labels = scales::comma) + scale_x_continuous(labels = scales::comma) + expand_limits(y = 0) + geom_smooth(se = FALSE, method = 'lm', colour = "gray48") + ggtitle(paste0("Lag", i)) + annotate( geom = 'text', label = paste0("R=", round(cor(pull(data2, x1), pull(data2, y1), use = "complete.obs", method = "spearman"), 2)), x = -Inf, y = Inf, hjust = 0, vjust = 1 ) plot_list[[i+1]] = p q = round(cor(pull(data2, x1), pull(data2, y1), use = "complete.obs", method = "spearman"), 2) corr[[i+1]] = q } return(plot_list) } dataset <- iris ui <- fluidPage( titlePanel("Example"), fluidRow( column(7, selectInput("variable1", "Variable 1:", choices = names(dataset[1:4]))), column(7, selectInput("variable2", "Variable 2:", choices = names(dataset[1:4])))), mainPanel( plotOutput("distPlot") ) ) server <- function(input, output) { output$distPlot <- renderPlot({ m <- scatter_fun(dataset, input$variable1, input$variable2) print(ggarrange(plotlist = m, ncol = 2, nrow = 3, common.legend = T)) }) } shinyApp(ui = ui, server = server)
关键修改点说明
sym(xval):将字符串格式的列名转换为ggplot和dplyr可以识别的符号对象,解决参数类型不匹配问题。pull(data2, x1):直接提取列数据,替代原有的data2[,"x1"],代码更简洁且避免潜在的索引错误。- 移除
corr<<-corr:函数内部的corr变量无需全局赋值,仅作为局部变量存储计算结果即可。
内容的提问来源于stack exchange,提问作者awz1
相关产品推荐
相关产品推荐

