簡體   English   中英

根據Shiny中的用戶輸入動態更改圖

[英]Dynamically change plots based on user input in Shiny

我正在嘗試創建一個閃亮的應用程序,該應用程序根據用戶對已加載數據框的子集的選擇來生成圖。 例如,我有以下數據集:

library(shiny)
library(data.table)

df <- rbind(
  data.table( cat = rep('X', 40), grp = rep(LETTERS[1:4], each=10), x = rep(1:10, times=4), y = rnorm(40) ),
  data.table( cat = rep('Y', 30), grp = rep(LETTERS[1:3], each=10), x = rep(1:10, times=3), y = rnorm(30) ),  
  data.table( cat = rep('Z', 20), grp = rep(LETTERS[4:6], each=10), x = rep(1:10, times=2), y = rnorm(20) )
)

根據用戶在UI中選擇的cat值,我希望Shiny為每個grp值生成圖表。 因此,如果用戶選擇“ X”,則將生成4個圖。 如果選擇“ Y”,則為3;如果選擇“ Z”,則為3。

我還想指定如何根據grp的值生成每個圖表。 因此,如果grp是A,D或EI,則希望它生成折線圖,否則應生成散點圖(僅當該grp當然具有該值時)。

以下是我(破損的)閃亮應用程序的代碼:

server <- function(input, output) {

  rv <- reactiveValues(
    i  = NULL,
    df = NULL
  )

  observe({ rv$i <- input$i })

  observe({ rv$df <- df[cat == rv$i] })

  output$test <- renderUI({
    plotList <- lapply( LETTERS[1:6], function(x) plotOutput(x) )

    do.call( tagList, unlist(plotList, recursive=FALSE))
  })

  for(i in LETTERS[1:6]){
    local({
      my_i <- i

      output[[my_i]] <- renderPlot({
        if( my_i %in% c('A','D','E')) {
          with(rv$df[grp == my_i], plot(x,y, type='l'))
        } else {
          with(rv$df[grp == my_i], plot(x,y))
        }
      })
    })
  }

}

ui <- fluidPage(
  titlePanel('Title'),

  sidebarLayout(
    sidebarPanel(
      helpText('Select the Category you would like to view.'),

      selectInput('i', 'Category', c('X','Y','Z'), selectize=TRUE)
    ),

    mainPanel(
      uiOutput('test')
    )
  )
)

shinyApp(ui, server)

在底部可以找到可復制的示例。

一些提示:

1)使用反應式上下文:

在服務器代碼底部的for循環中,您正在使用反應性變量rv ,因此您將必須在反應性內容中運行代碼。 因此將其包裝在observe()

2)創建輸出列表:

如果我沒記錯的話,您在此答案中使用了一些代碼:使用Shiny將圖動態添加到網頁中

這是一個很好的起點。 對於標簽列表而言,將其簡化為:

output$test <- renderUI({
    lapply(unique(rv$df$grp), plotOutput)
})

您還可以添加tagList() ,但是這里沒有必要,...

3)更正樣本數據:

您可能要更新df變量:

  data.table(cat = rep('Z', 20), grp = rep(LETTERS[4:6], each=10), 
             x = rep(1:10, times=2), y = rnorm(20) )

這里您有三個字母,因此您可以將其更改為LETTERS[5:6]或更新其他數字。

完整的可復制示例:

library(shiny)
library(data.table)

df <- rbind(
  data.table( cat = rep('X', 40), grp = rep(LETTERS[1:4], each=10), x = rep(1:10, times=4), y = rnorm(40) ),
  data.table( cat = rep('Y', 30), grp = rep(LETTERS[1:3], each=10), x = rep(1:10, times=3), y = rnorm(30) ),  
  data.table( cat = rep('Z', 30), grp = rep(LETTERS[4:6], each=10), x = rep(1:10, times=3), y = rnorm(30) )
)
server <- function(input, output) {

  rv <- reactiveValues(
    i  = NULL,
    df = NULL
  )

  observe({ rv$i <- input$i })

  observe({ rv$df <- df[cat == rv$i] })

  observe({
    for(letter in unique(rv$df$grp)){
      local({
        let <- letter
        output[[let]] <- renderPlot({
          if( let %in% c('A','D','E')) {
            with(rv$df[grp == let], plot(x, y, type='l'))
          } else {
            with(rv$df[grp == let], plot(x,y))
          }
        })
      })
    }
  })

  output$test <- renderUI({
    lapply(unique(rv$df$grp), plotOutput)
  })

}

ui <- fluidPage(
  titlePanel('Title'),
  sidebarLayout(
    sidebarPanel(
      helpText('Select the Category you would like to view.'),
      selectInput('i', 'Category', c('X','Y','Z'), selectize=TRUE)
    ),

    mainPanel(
      uiOutput('test')
    )
  )
)

shinyApp(ui, server)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM