R语言 根据用户输入文件的因子水平生成动态数量的图

tkclm6bt  于 2023-01-28  发布在  其他
关注(0)|答案(1)|浏览(89)

在一个闪亮的应用程序中,我想为用户输入的文件中的每个因子水平创建单独的图。这个因子可能有2到10+个水平。在玩具示例中,这个因子是plotGroup。我希望它像下面的玩具示例一样输出,但有单独的图而不是面。我已经使用这个脚本作为指导,但是我不能弄清楚如何在这个框架中适应React式getData()函数。https://gist.github.com/wch/5436415/
数据

structure(list(plotGroup = c("A", "A", "A", "A", "B", "B", "B", 
"B", "C", "C", "C", "C"), xGroup = c("D", "D", "E", "E", "D", 
"D", "E", "E", "D", "D", "E", "E"), yVar = c(5L, 8L, 1L, 6L, 
3L, 4L, 9L, 5L, 8L, 7L, 5L, 3L)), class = "data.frame", row.names = c(NA, 
-12L))

示例应用程序使用面提供所需输出

library(shiny)
library(data.table)
library(ggplot2)
library(dplyr)

ui <- fluidPage(
  
  headerPanel("Dynamic number of plots"),
  
  sidebarPanel(
    fileInput("fileIn", 
              "Load input file",
              multiple = F)
  ),
  
  mainPanel(
    plotOutput("plot1")
  )
)

server <- function(input, output) {
  
  getData <- reactive({
    req(input$fileIn)
    dataIn <- as.data.frame(fread(input$fileIn$datapath))
    return(dataIn)
  })
  
  output$plot1 <- renderPlot({
    getData() %>%
    ggplot(aes(x = xGroup, y = yVar)) +
      facet_wrap(~plotGroup) + geom_point()
  })
  
}

shinyApp(ui, server)

尝试使用上面的gist链接的示例。这将导致Operation not allowed without an active reactive context错误。

library(shiny)
library(data.table)
library(ggplot2)
library(dplyr)

ui <- fluidPage(
  
  headerPanel("Dynamic number of plots"),
  
  sidebarPanel(
    fileInput("fileIn", 
              "Load input file",
              multiple = F)
  ),
  
  mainPanel(
    uiOutput("plot1")
  )
)

server <- function(input, output) {
  
  getData <- reactive({
    req(input$fileIn)
    dataIn <- as.data.frame(fread(input$fileIn$datapath))
    return(dataIn)
  })
  
  output$plot1 <- renderUI({
    plotOutputList <- lapply(levels(getData()$plotGroup),
                             function(i){
                               plotname <- paste("plot", i, sep = "_")
                               plotOutput(plotname)
                             })
    do.call(tagList, plotOutputList)
  })
  
  for(i in levels(getData()$plotGroup)){
    local({
      iCurrent <- i
      plotname <- paste("plot", iCurrent, sep = "_")
      
      output[[plotname]] <- renderPlot({
        getData() %>%
          filter(plotGroup == iCurrent) %>%
        ggplot(aes(x = xGroup, y = yVar)) +
          geom_point()
      })
    })
  }
}

shinyApp(ui, server)
g2ieeal7

g2ieeal71#

这里有两个问题。首先,您共享的数据显示plotGroup是一个字符值,而不是一个因子。这意味着levels()将返回NULL,因为它没有任何值。您可以使用unique()而不是levels()来获取该列中的不同值。
第二个问题是for循环需要在一个被动的上下文中,最简单的解决方法就是将它 Package 在一个observe块中。
服务器函数应如下所示

server <- function(input, output) {
  
  getData <- reactive({
    return(data)
  })
  
  output$plot1 <- renderUI({
    plotOutputList <- lapply(unique(getData()$plotGroup),
                             function(i){
                               plotname <- paste("plot", i, sep = "_")
                               plotOutput(plotname)
                             })
    do.call(tagList, plotOutputList)
  })
  
  observe({
    for(i in unique(getData()$plotGroup)){
    local({
      iCurrent <- i
      plotname <- paste("plot", iCurrent, sep = "_")
      
      output[[plotname]] <- renderPlot({
        getData() %>%
          filter(plotGroup == iCurrent) %>%
          ggplot(aes(x = xGroup, y = yVar)) +
          geom_point()
      })
    })
  }})
}

相关问题