根据用户选择的图表类型呈现图表。

huangapple go评论50阅读模式
英文:

Render plot based on plot type selection from user

问题

我正在开发一个R Shiny应用程序,用于与森林清查数据进行交互,我希望创建一个流程,用户可以从侧边栏界面中选择直方图或箱线图,并且Shiny会在主面板中生成所选的图。

以下是我目前的Shiny应用程序代码,其中包含一些生成的数据,输出了直方图和箱线图。我希望根据侧边栏面板中的用户输入只生成其中一个图:

library(shiny)
library(tidyverse)
library(ggplot2)

setwd(getwd())

# 准备 CFI 数据
cfi <- data.frame(total_BA = rnorm(200, 90, 20),
                  all_QMD = rnorm(200, 8, 1.2),
                  class1 = rep(c(1, 2, 3, 4), times = 50),
                  class2 = rep(c('D', 'S'), times = 100)) %>%
  mutate_at(c('class1', 'class2'), as.factor)

##### 用户界面 #####
ui <- fluidPage(
  titlePanel("CFI Viewer"),
  
  sidebarLayout(
    
    sidebarPanel("侧边栏面板标题",
                 
                 selectInput("plot.type",
                             label = "选择图形类型",
                             choices = c('直方图', '箱线图'),
                             selected = "直方图"),
                 
                 selectInput("var",
                             label = "选择要显示的变量",
                             choices = colnames(cfi[, c(1:2)]),
                             selected = "total_BA"),
                 
                 sliderInput(inputId = "bins",
                             label = "选择直方图的柱数",
                             min = 5,
                             max = 50,
                             value = 15),
                 
                 selectInput(inputId = "fac",
                             label = "选择箱线图的因子",
                             choices = c('class1', 'class2'),
                             selected = 'class1')
    ),
    
    mainPanel("主面板标题",
              
              fluidRow(plotOutput('hist')),
              
              fluidRow(tableOutput('hist.sum')),
              
              fluidRow(plotOutput('box')),
              
              fluidRow(tableOutput('box.sum'))
    )
  )
)


##### 服务器 #####
server <- function(input, output, session) {
  
  output$hist <- renderPlot({
    ggplot(cfi, aes(x = get(input$var))) + 
      geom_histogram(bins = input$bins, color = "black", fill="darkgray") 
  })
  
  output$hist.sum <- renderTable({
    cfi %>%
      summarize(Min = min(get(input$var), na.rm = TRUE),
                Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
                Median = median(get(input$var), na.rm = TRUE),
                Mean = mean(get(input$var), na.rm = TRUE),
                Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
                Max = max(get(input$var), na.rm = TRUE),
                NAs = sum(is.na(get(input$var)))
      )
  })
  
  output$box <- renderPlot({
    ggplot(cfi, aes(x = get(input$fac), y = get(input$var))) + 
      geom_boxplot(na.rm = TRUE) +
      stat_summary(fun.y = mean, geom = "point", shape = 19, size = 2, na.rm = TRUE)
  })
  
  output$box.sum <- renderTable({
    box.sum <- cfi %>%
      group_by(get(input$fac)) %>%
      summarize(Min = min(get(input$var), na.rm = TRUE),
                Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
                Median = median(get(input$var), na.rm = TRUE),
                Mean = mean(get(input$var), na.rm = TRUE),
                Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
                Max = max(get(input$var), na.rm = TRUE),
                N = n())
    colnames(box.sum) <- c(input$fac, 'Min', 'Q1', 'Median', 'Mean', 'Q3', 'Max', 'N')
    box.sum
  })
  
}


##### 启动应用程序 #####
shinyApp(ui = ui, server = server)
英文:

I'm developing an R Shiny App to interact with forest inventory data and I want to create a process where a user selects either a Histogram or Box Plot from the sidebar interface and Shiny generates the selected plot in the main panel.

Below is my current code for the Shiny App with some generated data that outputs both the Histogram and Box plots. I would like for only one of these to be generated based on the user input in the sidebar panel:

library(shiny)
library(tidyverse)
library(ggplot2)
setwd(getwd())
# Prep CFI Data
cfi &lt;- data.frame(total_BA = rnorm(200, 90, 20),
all_QMD = rnorm(200, 8, 1.2),
class1 = rep(c(1, 2, 3, 4), times = 50),
class2 = rep(c(&#39;D&#39;, &#39;S&#39;), times = 100)) %&gt;% 
mutate_at(c(&#39;class1&#39;, &#39;class2&#39;), as.factor)
##### User-Interface #####
ui &lt;- fluidPage(
titlePanel(&quot;CFI Viewer&quot;),
sidebarLayout(
sidebarPanel(&quot;sidebar panel title&quot;,
selectInput(&quot;plot.type&quot;,
label = &quot;Select plot type&quot;,
choices = c(&#39;Histogram&#39;, &#39;Box Plot&#39;),
selected = &quot;Histogram&quot;),
selectInput(&quot;var&quot;,
label = &quot;Choose a variable to display&quot;,
choices = colnames(cfi[, c(1:2)]),
selected = &quot;total_BA&quot;),
sliderInput(inputId = &quot;bins&quot;,
label = &quot;Select # of bins for histogram&quot;,
min = 5,
max = 50,
value = 15),
selectInput(inputId = &quot;fac&quot;,
label = &quot;Choose a factor for box plot&quot;,
choices = c(&#39;class1&#39;, &#39;class2&#39;),
selected = &#39;class1&#39;)
),
mainPanel(&quot;main panel title&quot;,
fluidRow(plotOutput(&#39;hist&#39;)),
fluidRow(tableOutput(&#39;hist.sum&#39;)),
fluidRow(plotOutput(&#39;box&#39;)),
fluidRow(tableOutput(&#39;box.sum&#39;))
)
)
)
##### Server #####
server &lt;- function(input, output, session) {
output$hist &lt;- renderPlot({
ggplot(cfi, aes(x = get(input$var))) + 
geom_histogram(bins = input$bins, color = &quot;black&quot;, fill=&quot;darkgray&quot;) 
})
output$hist.sum &lt;- renderTable({
cfi %&gt;% 
summarize(Min = min(get(input$var), na.rm = TRUE),
Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
Median = median(get(input$var), na.rm = TRUE),
Mean = mean(get(input$var), na.rm = TRUE),
Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
Max = max(get(input$var), na.rm = TRUE),
NAs = sum(is.na(get(input$var)))
)
})
output$box &lt;- renderPlot({
ggplot(cfi, aes(x = get(input$fac), y = get(input$var))) + 
geom_boxplot(na.rm = TRUE) +
stat_summary(fun.y = mean, geom = &quot;point&quot;, shape = 19, size = 2, na.rm = TRUE)
})
output$box.sum &lt;- renderTable({
box.sum &lt;- cfi %&gt;% 
group_by(get(input$fac)) %&gt;% 
summarize(Min = min(get(input$var), na.rm = TRUE),
Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
Median = median(get(input$var), na.rm = TRUE),
Mean = mean(get(input$var), na.rm = TRUE),
Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
Max = max(get(input$var), na.rm = TRUE),
N = n())
colnames(box.sum) &lt;- c(input$fac, &#39;Min&#39;, &#39;Q1&#39;, &#39;Median&#39;, &#39;Mean&#39;, &#39;Q3&#39;, &#39;Max&#39;, &#39;N&#39;)
box.sum
})
}
##### Launch App #####
shinyApp(ui = ui, server = server)

答案1

得分: 1

需要使用 observeEvent 来观察并根据用户选择切换图表。我已经修改了您的代码,根据下拉选择在直方图和箱线图之间切换。

library(shiny)
library(tidyverse)
library(ggplot2)

setwd(getwd())

# 准备 CFI 数据
cfi <- data.frame(total_BA = rnorm(200, 90, 20),
                  all_QMD = rnorm(200, 8, 1.2),
                  class1 = rep(c(1, 2, 3, 4), times = 50),
                  class2 = rep(c('D', 'S'), times = 100)) %>%
  mutate_at(c('class1', 'class2'), as.factor)

##### 用户界面 #####
ui <- fluidPage(
  titlePanel("CFI Viewer"),

  sidebarLayout(

    sidebarPanel("侧边栏标题",

                 selectInput("plot.type",
                             label = "选择图表类型",
                             choices = c('直方图', '箱线图'),
                             selected = "直方图"),

                 selectInput("var",
                             label = "选择要显示的变量",
                             choices = colnames(cfi[, c(1:2)]),
                             selected = "total_BA"),

                 sliderInput(inputId = "bins",
                             label = "选择直方图的柱数",
                             min = 5,
                             max = 50,
                             value = 15),

                 selectInput(inputId = "fac",
                             label = "选择箱线图的因子",
                             choices = c('class1', 'class2'),
                             selected = 'class1')
    ),

    mainPanel("主面板标题",

              fluidRow(plotOutput('plot')),

              fluidRow(tableOutput('data.sum'))

    )
  )
)

##### 服务器 #####
server <- function(input, output, session) {

  observeEvent(input$plot.type,{
    if(input$plot.type == '直方图'){
      output$plot <- renderPlot({

        ggplot(cfi, aes(x = get(input$var))) + 
          geom_histogram(bins = input$bins, color = "black", fill="darkgray") 
      })

      output$data.sum <- renderTable({
        cfi %>%
          summarize(Min = min(get(input$var), na.rm = TRUE),
                    Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
                    Median = median(get(input$var), na.rm = TRUE),
                    Mean = mean(get(input$var), na.rm = TRUE),
                    Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
                    Max = max(get(input$var), na.rm = TRUE),
                    NAs = sum(is.na(get(input$var)))
          )
      })

    } else if(input$plot.type == '箱线图'){
      output$plot <- renderPlot({
        ggplot(cfi, aes(x = get(input$fac), y = get(input$var))) + 
          geom_boxplot(na.rm = TRUE) +
          stat_summary(fun.y = mean, geom = "point", shape = 19, size = 2, na.rm = TRUE)
      })

      output$data.sum <- renderTable({
        box.sum <- cfi %>%
          group_by(get(input$fac)) %>%
          summarize(Min = min(get(input$var), na.rm = TRUE),
                    Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
                    Median = median(get(input$var), na.rm = TRUE),
                    Mean = mean(get(input$var), na.rm = TRUE),
                    Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
                    Max = max(get(input$var), na.rm = TRUE),
                    N = n())
        colnames(box.sum) <- c(input$fac, 'Min', 'Q1', 'Median', 'Mean', 'Q3', 'Max', 'N')
        box.sum
      })
    }
  })

}

##### 启动应用程序 #####
shinyApp(ui = ui, server = server)

请注意,我将代码中的英文文本翻译为中文。

英文:

You need observeEvent to observe and act based on the user selection to toggle between the plots. I have modified your code to switch between the histogram and box plot based on the dropdown selection.

library(shiny)
library(tidyverse)
library(ggplot2)
setwd(getwd())
# Prep CFI Data
cfi &lt;- data.frame(total_BA = rnorm(200, 90, 20),
all_QMD = rnorm(200, 8, 1.2),
class1 = rep(c(1, 2, 3, 4), times = 50),
class2 = rep(c(&#39;D&#39;, &#39;S&#39;), times = 100)) %&gt;% 
mutate_at(c(&#39;class1&#39;, &#39;class2&#39;), as.factor)
##### User-Interface #####
ui &lt;- fluidPage(
titlePanel(&quot;CFI Viewer&quot;),
sidebarLayout(
sidebarPanel(&quot;sidebar panel title&quot;,
selectInput(&quot;plot.type&quot;,
label = &quot;Select plot type&quot;,
choices = c(&#39;Histogram&#39;, &#39;Box Plot&#39;),
selected = &quot;Histogram&quot;),
selectInput(&quot;var&quot;,
label = &quot;Choose a variable to display&quot;,
choices = colnames(cfi[, c(1:2)]),
selected = &quot;total_BA&quot;),
sliderInput(inputId = &quot;bins&quot;,
label = &quot;Select # of bins for histogram&quot;,
min = 5,
max = 50,
value = 15),
selectInput(inputId = &quot;fac&quot;,
label = &quot;Choose a factor for box plot&quot;,
choices = c(&#39;class1&#39;, &#39;class2&#39;),
selected = &#39;class1&#39;)
),
mainPanel(&quot;main panel title&quot;,
fluidRow(plotOutput(&#39;plot&#39;)),
fluidRow(tableOutput(&#39;data.sum&#39;))
)
)
)
##### Server #####
server &lt;- function(input, output, session) {
observeEvent(input$plot.type,{
if(input$plot.type == &#39;Histogram&#39;){
output$plot &lt;- renderPlot({
ggplot(cfi, aes(x = get(input$var))) + 
geom_histogram(bins = input$bins, color = &quot;black&quot;, fill=&quot;darkgray&quot;) 
})
output$data.sum &lt;- renderTable({
cfi %&gt;% 
summarize(Min = min(get(input$var), na.rm = TRUE),
Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
Median = median(get(input$var), na.rm = TRUE),
Mean = mean(get(input$var), na.rm = TRUE),
Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
Max = max(get(input$var), na.rm = TRUE),
NAs = sum(is.na(get(input$var)))
)
})
} else if(input$plot.type == &#39;Box Plot&#39;){
output$plot &lt;- renderPlot({
ggplot(cfi, aes(x = get(input$fac), y = get(input$var))) + 
geom_boxplot(na.rm = TRUE) +
stat_summary(fun.y = mean, geom = &quot;point&quot;, shape = 19, size = 2, na.rm = TRUE)
})
output$data.sum &lt;- renderTable({
box.sum &lt;- cfi %&gt;% 
group_by(get(input$fac)) %&gt;% 
summarize(Min = min(get(input$var), na.rm = TRUE),
Q1 = quantile(get(input$var), 0.25, na.rm = TRUE),
Median = median(get(input$var), na.rm = TRUE),
Mean = mean(get(input$var), na.rm = TRUE),
Q3 = quantile(get(input$var), 0.75, na.rm = TRUE),
Max = max(get(input$var), na.rm = TRUE),
N = n())
colnames(box.sum) &lt;- c(input$fac, &#39;Min&#39;, &#39;Q1&#39;, &#39;Median&#39;, &#39;Mean&#39;, &#39;Q3&#39;, &#39;Max&#39;, &#39;N&#39;)
box.sum
})
}
})
}
##### Launch App #####
shinyApp(ui = ui, server = server)

huangapple
  • 本文由 发表于 2023年7月7日 02:00:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76631446.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定