Невозможно добавить объекты ggproto вместе

В настоящее время я работаю над приложением Rshiny. Мне пришлось сделать несколько диаграмм с несколькими выбранными входами и флажком. Я почти закончил свою задачу, и теперь мне просто нужно сделать так, чтобы каждый раз, когда я меняю выбранный вид, масштаб оставался прежним (если, конечно, не были введены другие переменные).

Мой код выглядит так:

library(shiny)
library(palmerpenguins)
library(dplyr)
library(ggplot2)

data <- na.omit(penguins)

colnames(data) <- c("Species",
                    "Island",
                    "Bill Length (mm)",
                    "Bill Depth (mm)", 
                    "Flipper Length (mm)",
                    "Body Mass (g)",
                    "Sex",
                    "Year")

data.numeric <- data[, c(3:6, 8)]

data.categorical <- data[, c(1,7)]


ui <- fluidPage(
  headerPanel("Penguin boxplots"),
  selectInput("ycol", 
              "Numeric Variable", 
              names(data.numeric),
              selected = names(data.numeric)[3]),
  selectInput("xcol",
              "Categorical Variable",
              names(data.categorical),
              selected = names(data.categorical)[2]),
  checkboxInput("split",
                "Split levels by Island",
                value = FALSE),
  selectInput("species",
              "Species Type",
              c("Unspecified", levels(data$Species))),
  mainPanel(
    plotOutput("plot1")
  ))






# 4. Use a select input to allow the user to view separate plotting 
# panels for each species, with each plot panel on the same scale.


server <- function(input, output){
  output$plot1 <- renderPlot({
    par(mar = c(5, 4.1, 0, 1))
    
    if (input$species == "Unspecified"){
      
      
      
      
      if (input$split) {
        ggplot(data, aes(x = data[[input$xcol]], y = data[[input$ycol]], fill = Island)) +
          geom_boxplot(na.rm = TRUE) +
          
          if (input$ycol == "Bill Length (mm)"){
              coord_cartesian(ylim = c(30, 60)) 
          } else if (input$ycol == "Bill Depth (mm)"){
            coord_cartesian(ylim = c(12.5, 21.5)) 
          } else if (input$ycol == "Flipper Length(mm)"){
            coord_cartesian(ylim = c(170, 232)) 
          } else if (input$ycol == "Body Mass (g)"){
            coord_cartesian(ylim = c(2500, 6500))
          } else if (input$ycol == "Year"){
            coord_cartesian(ylim = c(2006, 2009))
          } +
          xlab(input$xcol) +
          ylab(input$ycol) + 
          scale_x_discrete(labels = c("Female", "Male")) +
          theme(text = element_text(size = 15))
        
      } else {
        ggplot(data, aes(x = data[[input$xcol]], y = data[[input$ycol]])) +
          geom_boxplot(na.rm = TRUE) +
          if (input$ycol == "Bill Length (mm)"){
            coord_cartesian(ylim = c(30, 60)) 
          } else if (input$ycol == "Bill Depth (mm)"){
            coord_cartesian(ylim = c(12.5, 21.5)) 
          } else if (input$ycol == "Flipper Length(mm)"){
            coord_cartesian(ylim = c(170, 232)) 
          } else if (input$ycol == "Body Mass (g)"){
            coord_cartesian(ylim = c(2500, 6500))
          } else if (input$ycol == "Year"){
            coord_cartesian(ylim = c(2006, 2009))
          } +
          xlab(input$xcol) +
          ylab(input$ycol) +
          theme(text = element_text(size = 15))
      }
      
      
      
      
      
      
      
    } else {
      
      
      
      
      
      data <- data %>%
        filter(data$Species == input$species)
      if (input$split) {
        ggplot(data, aes(x = data[[input$xcol]], y = data[[input$ycol]], fill = Island)) +
          geom_boxplot(na.rm = TRUE) +
          xlab(input$xcol) +
          ylab(input$ycol) + 
          scale_x_discrete(labels = c("Female", "Male")) +
          theme(text = element_text(size = 15))
        
      } else {
        ggplot(data, aes(x = data[[input$xcol]], y = data[[input$ycol]])) +
          geom_boxplot(na.rm = TRUE) +
          xlab(input$xcol) +
          ylab(input$ycol) +
          theme(text = element_text(size = 15))
      }
    }
    
    
  })
}

















shinyApp(ui = ui, server = server)

Проблема возникает, когда я запускаю строки, содержащие else if (input$ycol == "Year"){ coord_cartesian(ylim = c(2006, 2009))}, когда я получаю следующую ошибку: Невозможно добавить объекты ggproto вместе. Вы забыли добавить этот объект в объект ggplot?

Я не уверен, где я ошибаюсь, или я просто пропускаю какую-то синтаксическую ошибку.

p.s. Код не закончен — мне все еще нужно добавить код для управления масштабами, когда вид не является «неуказанным», но я не буду этого делать, пока не выясню это.

Попробуйте просто else в последнем операторе ggplot вместо if else.

Eric Krantz 11.12.2020 00:12

Видите ли, я думал об этом раньше и пробовал, но это не сработало. Я снова изменил его на это, и он все еще не работает. Все равно пишет ту же ошибку. Вот строка кода: else { coord_cartesian(ylim = c(2006, 2009))}

Rhys Mc 11.12.2020 00:16
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
1 618
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете упростить ситуацию, создав функцию, которая возвращает желаемое выражение coord_cartesian. Затем функцию можно добавить в цепочку ggplot с помощью +, как в обычном рабочем процессе ggplot.

В приведенном ниже примере используются жестко запрограммированные варианты из вашего примера. Однако, если вы можете предоставить больше информации о том, как выбираются эти диапазоны, можно получить диапазон y более автоматизированным способом, вместо того, чтобы явно жестко запрограммировать каждый возможный случай.

В приведенном ниже примере оператор case_when возвращает соответствующие значения ylim для передачи в coord_cartesian. Если input$ycol не соответствует ни одному из параметров, case_when вернет ylim=c(NA,NA), что приведет к тому, что ggplot сохранит диапазон осей по умолчанию.

# I've included only 3 choices. Add in as many additional choices as needed.
coord_fnc = function(x=input$ycol) {
  ylim = dplyr::case_when(
      x= = "Bill Length (mm)" ~ c(30,60),
      x= = "Flipper Length(mm)" ~ c(170, 232),
      x= = "Bill Depth (mm)" ~ c(12.5,21.5)
  )
  coord_cartesian(ylim=ylim)
}


ggplot(data, aes(x = data[[input$xcol]], y = data[[input$ycol]], fill = Island)) +
  geom_boxplot(na.rm = TRUE) +
  coord_fnc() +
  xlab(input$xcol) +
  ylab(input$ycol) +
  theme(text = element_text(size = 15))

Попробуйте это со встроенным фреймом данных mtcars:

ggplot(mtcars, aes(hp, mpg)) + 
  geom_point() + 
  coord_fnc("Bill Length (mm)")

Хотя строка операторов if else занимает много кода, этот подход может работать, и я не уверен, почему вы получаете сообщение об ошибке (это может быть какая-то другая часть кода). Например, это работает:

input = list(ycol = "Year")

ggplot(mtcars, aes(hp, mpg)) + 
  geom_point() + 
  if (input$ycol == "Bill Length (mm)"){
    coord_cartesian(ylim = c(30, 60)) 
  } else if (input$ycol == "Bill Depth (mm)"){
    coord_cartesian(ylim = c(12.5, 21.5)) 
  } else if (input$ycol == "Flipper Length(mm)"){
    coord_cartesian(ylim = c(170, 232)) 
  } else if (input$ycol == "Body Mass (g)"){
    coord_cartesian(ylim = c(2500, 6500))
  } else if (input$ycol == "Year"){
    coord_cartesian(ylim = c(2006, 2009))
  }

Другие вопросы по теме