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

Shiny中selectInput传递含引号的ggplot位置参数报错求助

解决Shiny中selectInput传递position参数出错的问题

这个问题我之前也碰到过,核心原因是你把position的函数调用当成字符串传给ggplot了——ggplot的position参数需要的是实际的Position类对象,而不是文本字符串,所以直接传字符串会导致它找不到对应的position方法,自然报错。

下面给你两种可行的解决方案:

方法一:用标识值配合switch判断(推荐,更安全)

先修改你的ui.R里的selectInput,把选项值改成简单的标识(比如"dodge"和"stack"),这样更清晰也更安全:

selectInput("posicion", "Visualizar Barras", 
            list("Agrupadas" = "dodge", 
                 "Sumadas" = "stack"))

然后在server.R里,根据选择的标识值生成对应的position对象:

output$g_virus_x_semana.1 <- renderPlot({
  # 根据选择获取对应的position对象
  selected_pos <- switch(input$posicion,
                "dodge" = position_dodge2(preserve = "single"),
                "stack" = position_stack())
  
  ggplot(subset(v, v$año == input$año.1 & Virus %in% input$virus), 
         aes(semana, fill = Virus)) +
    geom_bar(position = selected_pos, stat = "count") +
    scale_x_discrete(drop = FALSE) +
    scale_fill_virus() +
    theme_dark() +
    labs(y = "N° de virus identificados", x = "Semana")
})

方法二:将字符串转换为可执行代码(适合不想修改ui的场景)

如果你不想改动ui里的选项值,可以用eval(parse())把字符串形式的代码转换成实际执行的函数调用,但要注意这种方法存在代码注入风险,仅适合自己可控的应用:

output$g_virus_x_semana.1 <- renderPlot({
  # 把字符串转换成可执行代码并生成position对象
  selected_pos <- eval(parse(text = input$posicion))
  
  ggplot(subset(v, v$año == input$año.1 & Virus %in% input$virus), 
         aes(semana, fill = Virus)) +
    geom_bar(position = selected_pos, stat = "count") +
    scale_x_discrete(drop = FALSE) +
    scale_fill_virus() +
    theme_dark() +
    labs(y = "N° de virus identificados", x = "Semana")
})

为什么原来的方法会报错?

当你直接在ggplot里写position_dodge2(preserve = "single")时,R会立刻执行这个函数,返回一个PositionDodge2类的对象,ggplot可以直接使用;但你通过selectInput传递的是字符串"position_dodge2(preserve = "single")",ggplot会把它当成position方法的名字去查找,自然找不到对应的方法,所以抛出Can't find position called "..."的错误。

内容的提问来源于stack exchange,提问作者Felipe Reyes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:18:53