简体   繁体   中英

Radar plot in R Shiny

I'm really new to R Shiny (starting playing with it today,). but this code isn't working for me... R keeps saying "the data must be given as dataframe," which, as far as I can tell. it is a dataframe (and it says it is when I check with is.data.frame).

# Load packages ----
library(shiny)
library(fmsb)

# Load data ----
industry <- read.csv("data/industry.csv")

# User interface ----
ui <- fluidPage(
  titlePanel("L&D Capabilities 2023"),
  
  sidebarLayout(
    sidebarPanel(
      helpText("Check which L&D capabilities your industry
      has in-house in 2023."),
      
      selectInput("var", 
                  label = "Choose a variable to display",
                  choices = c("Central government", 
                              "Local government",
                              "IT and Telecoms", 
                              "Professional services, law and accountancy", 
                              "Finance, banking and insurance", 
                              "Health", 
                              "Social care/housing association", 
                              "Other charity/voluntary sector", 
                              "Retail", 
                              "Engineering", 
                              "Manufacturing", 
                              "Pharmaceutical", 
                              "Transport", 
                              "Utilities", 
                              "Hospitality", 
                              "Education (HE, FE)", 
                              "Art, media and design", 
                              "Other", 
                              "Consulting"),
                  selected = "Central government"),
    ),
    
    mainPanel(plotOutput("radarPlot"))
  )
)

# Server logic ----
server <- function(input, output) {
  output$radarPlot <- renderPlot({
    data <- switch(input$var, 
                   "Central government" = industry$Centralgov,
                   "Local government" = industry$Localgov,
                   "IT and Telecoms" = industry$IT,
                   "Professional services, law and accountancy" = industry$PS,
                   "Finance, banking and insurance" = industry$Finance,
                   "Health" = industry$Health,
                   "Social care/housing association" = industry$Social,
                   "Other charity/voluntary sector" = industry$Charity,
                   "Retail" = industry$Retail,
                   "Engineering" = industry$Engineering,
                   "Manufacturing" = industry$Manufacturing,
                   "Pharmaceutical" = industry$Pharmaceutical,
                   "Transport" = industry$Transport,
                   "Utilities" = industry$Utilities,
                   "Hospitality" = industry$Hospitality,
                   "Education (HE, FE)" = industry$Education,
                   "Consulting" = industry$Consulting,
                   "Art, media and design" = industry$Art,
                   "Other" = counties$Other)
    
    radarchart(data)
  })
}

# Run app ----
shinyApp(ui, server)

Any ideas what's going on? Or what I'm missing?

Many thanks!

EDIT: here's my data

> dput(industry)
structure(list(Max = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), Min = c(0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), Centralgov = c(0.6, 
0.18, 0.27, 0.27, 0.27, 0.27, 0.36, 0.3, 0.55, 0.45, 0.1, 0, 
0.1, 0.27, 0.64, 0.09, 0.09, 0.18, 0.27, 0, 0.09, 0.18, 0.25, 
0.29, 0.14), Localgov = c(0.36, 0.5, 0.36, 0.5, 0.42, 0.42, 0.09, 
0.27, 0.36, 0.55, 0.3, 0.36, 0.55, 0.45, 0.73, 0.36, 0.18, 0.45, 
0.64, 0.36, 0.27, 0.18, 0.3, 0.2, 0.6), IT = c(0.73, 0.33, 0.47, 
0.51, 0.38, 0.18, 0.34, 0.38, 0.62, 0.41, 0.19, 0.38, 0.49, 0.41, 
0.62, 0.32, 0.22, 0.38, 0.58, 0.51, 0.33, 0.34, 0.41, 0.15, 0.37
), PS = c(0.73, 0.4, 0.56, 0.6, 0.48, 0.48, 0.29, 0.24, 0.63, 
0.56, 0.29, 0.41, 0.27, 0.36, 0.71, 0.28, 0.16, 0.48, 0.4, 0.52, 
0.36, 0.38, 0.29, 0.25, 0.13), Finance = c(0.9, 0.44, 0.66, 0.66, 
0.61, 0.52, 0.44, 0.5, 0.86, 0.62, 0.32, 0.39, 0.48, 0.59, 0.86, 
0.3, 0.27, 0.5, 0.52, 0.52, 0.57, 0.51, 0.56, 0.33, 0.29), Health = c(0.88, 
0.33, 0.47, 0.65, 0.28, 0.37, 0.33, 0.29, 0.78, 0.47, 0.18, 0.13, 
0.47, 0.5, 0.78, 0.26, 0.16, 0.41, 0.58, 0.5, 0.38, 0.39, 0.33, 
0.13, 0.29), Social = c(0.7, 0.25, 0.5, 0.33, 0.3, 0.2, 0.1, 
0.4, 0.5, 0.2, 0, 0.22, 0, 0.2, 0.4, 0.1, 0.3, 0.1, 0.3, 0.3, 
0.33, 0.3, 0.33, 0, 0.11), Charity = c(0.8, 0.55, 0.62, 0.44, 
0.5, 0.31, 0.08, 0.33, 0.58, 0.5, 0.4, 0.36, 0.33, 0.38, 0.82, 
0.15, 0.08, 0.36, 0.22, 0.42, 0.2, 0.42, 0.18, 0.22, 0.11), Retail = c(0.62, 
0.38, 0.46, 0.27, 0.25, 0.09, 0.08, 0.31, 0.82, 0.46, 0.25, 0.27, 
0.25, 0.54, 0.69, 0.08, 0.17, 0.31, 0.67, 0.5, 0.33, 0.5, 0.38, 
0.18, 0.08), Engineering = c(0.6, 0, 0.4, 0.25, 0.17, 0.17, 0, 
0, 0.33, 0.5, 0.25, 0.33, 0.6, 0.17, 0.33, 0, 0, 0.33, 0.33, 
0.17, 0.17, 0.5, 0.2, 0, 0), Manufacturing = c(0.56, 0.22, 0.35, 
0.42, 0.42, 0.4, 0.24, 0.2, 0.56, 0.41, 0.24, 0.11, 0.21, 0.3, 
0.63, 0.1, 0, 0.25, 0.42, 0.58, 0.21, 0.35, 0.25, 0.33, 0.06), 
    Pharmaceutical = c(0.43, 0.25, 0, 0.71, 0.63, 0.25, 0.13, 
    0.13, 0.63, 0.43, 0, 0, 0, 0, 0.38, 0.25, 0.13, 0.38, 0.38, 
    0.5, 0, 0, 0.33, 0, 0.17), Transport = c(0.77, 0.62, 0.79, 
    0.57, 0.71, 0.64, 0.14, 0.5, 0.79, 0.46, 0.38, 0.21, 0.36, 
    0.38, 0.64, 0.43, 0.29, 0.21, 0.57, 0.64, 0.29, 0.54, 0.57, 
    0.36, 0.15), Utilities = c(1, 0.6, 0.4, 0.33, 0.2, 0.2, 0.6, 
    0.6, 0.8, 0.6, 0.25, 0.2, 0.8, 0.4, 1, 0.4, 0.4, 0.6, 0.4, 
    0.6, 0.2, 0.2, 0.2, 0.2, 0), Hospitality = c(0.67, 0, 0.67, 
    0.4, 0.67, 0.33, 0.33, 0.83, 0.83, 0.2, 0.67, 0.17, 0.2, 
    0.33, 0.83, 0.33, 0.33, 0, 0.67, 1, 0.5, 0.33, 0.33, 0.6, 
    0.33), Education = c(0.87, 0.33, 0.47, 0.53, 0.41, 0.38, 
    0.5, 0.47, 0.65, 0.41, 0.2, 0.31, 0.47, 0.65, 0.53, 0.24, 
    0.29, 0.38, 0.56, 0.41, 0.31, 0.19, 0.38, 0.27, 0.35), Consulting = c(0.67, 
    0.5, 0.67, 1, 0.33, 0.33, 0.17, 0.5, 1, 0.6, 0.33, 0.6, 0.4, 
    0.67, 0.5, 0.17, 0.17, 0.4, 0.6, 0.5, 0.5, 0.33, 0.4, 0.25, 
    0.25), Art = c(1, 0.2, 0.6, 0.5, 0.4, 0.2, 0.2, 0.6, 0.6, 
    0.4, 0.2, 0.2, 0.6, 0.5, 0.5, 0.2, 0.2, 0.2, 0.2, 0.6, 0.4, 
    0.4, 0.4, 0.2, 0.25), Other = c(0.67, 0.57, 0.71, 0.29, 0.57, 
    0.43, 0.14, 0.5, 0.67, 0.29, 0.57, 0.29, 0.43, 0.57, 0.71, 
    0.29, 0.43, 0.29, 0.43, 0.57, 0.71, 0.43, 0.5, 0.6, 0.4)), class = "data.frame", row.names = c("In-person classroom delivery", 
"Strategy and governance", "Stakeholder engagement", "Instructional design", 
"Crafting learning journeys / blended solutions", "Supporting ongoing workplace performance", 
"Facilitating social and collaborative learning", "Understanding learner behaviour", 
"Virtual classroom / webinar delivery", "Digital content development", 
"Performance consulting", "Business acumen", "Marketing and communications", 
"Coaching and mentoring", "Learning management / administration", 
"Analytics / data management", "Evaluating impact", "Technology/infrastructure", 
"Project management", "Leveraging L&D expertise", "Knowledge management", 
"Negotiation, persuasion, and influence", "Learning experience design", 
"Community engagement", "Research capabilities"))

Like I mentioned in my comment, radarchart requires at least three variables.

In this solution, I set the plot to only render when there are at least three options selected. I've changed the creation of the dropdown to allow multiple selections (so that three can be selected.

ui <- fluidPage(
  titlePanel("Title"),
  sidebarLayout(sidebarPanel(
    helpText("help goes here"),
    selectInput(
      "var", label = "Choose at least three options to plot", 
      multiple = T, 
      choices = setNames(
          names(industry)[3:21], 
          c("Central government", "Local government", "IT and Telecoms",
            "Professional services, law and accountancy", 
            "Finance, banking and insurance", "Health", 
            "Social care/housing association", "Other charity/voluntary sector", 
            "Retail", "Engineering","Manufacturing", "Pharmaceutical", "Transport", 
            "Utilities", "Hospitality", "Education (HE, FE)", "Consulting", 
            "Art, media and design", "Other")), selected = "Central government")
      ), mainPanel(plotOutput("radarPlot")))
  )

server <- function(input, output, session) {
  output$radarPlot <- renderPlot({
    if(length(input$var) >= 3) {
      radarchart(industry[, input$var])
    }
  })
}

# Run app ----
shinyApp(ui, server)

在此处输入图像描述

However, this is not technically accurate since the first row is supposed to be the max value. The second row is supposed to be the min value. (Which is how your data frame is orientated if you transpose it.)

Here's another version of the server. In this version, I've modified the data so that the first and second rows are the max and min.

# add max and min to the top of every column
industry2 <- t(industry) %>% 
  as.data.frame() %>% 
  mutate(max = 1, min = 0) %>% 
  select(max, min, everything()) %>% 
  t() %>% as.data.frame()

server2 <- function(input, output, session) {
  output$radarPlot <- renderPlot({
    if(length(input$var) >= 3) {
      radarchart(industry[, input$var])
    }
  })
}

# Run app ----
shinyApp(ui, server2)

This renders an identical plot to what I pictured for the first version (so I am not sure why the radarchart function calls for this information.)


I'm not sure how attached you are to fmsb::radarchart , but there are a lot of other options: ggplot2 , plotly , highcharter , echarts , etc.

Here's an alternative using the Plotly library. In this option, I've set multiple in selectInput to false (based on what you were originally trying to plot). I've set the range so the graphs are comparable. A few other changes are annotated in the comments in the code.

library(plotly)
library(shiny)

ui2 <- fluidPage(
  titlePanel("With Plotly"),
  sidebarLayout(sidebarPanel(
    helpText("help goes here"),
    selectInput(
      "var", label = "Choose a field to plot", 
      multiple = F,      # <<- FALSE now (can remove argument, default is false)
      choices = setNames(
        names(industry)[3:21], 
        c("Central government", "Local government", "IT and Telecoms",
          "Professional services, law and accountancy", 
          "Finance, banking and insurance", "Health", 
          "Social care/housing association", "Other charity/voluntary sector", 
          "Retail", "Engineering","Manufacturing", "Pharmaceutical", "Transport", 
          "Utilities", "Hospitality", "Education (HE, FE)", "Consulting", 
          "Art, media and design", "Other")), selected = "Central government")
  ), mainPanel(plotlyOutput("radarPlot"))) # <<-- plotlyOutput instead of plotOutput
)

server3 <- function(input, output, session) {
  output$radarPlot <- renderPlotly({ # <- render plotly instead of plot
      plot_ly(r = industry[, input$var], theta = rownames(industry),
              fill = "toself", type = "scatterpolar", mode = "markers") %>% 
      layout(
        polar = list(
        angularaxis = list(showticklabels = F),
        radialaxis = list(range = c(0, 1))
      ))
  })
}
# Run app ----
shinyApp(ui2, server3)

I hid the labels, because they overlapped. However, when you hover, you can see the row names.

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM