Я пытался соединить свой вход с выходом моего графика в блестящем - но я всегда получаю ошибку - PullRequest
1 голос
/ 11 мая 2019

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

У меня есть следующий набор данных:

year <- c(2000, 2002, 2006, 2000, 2004, 2010, 2010, 2011, 2020, 2006)
prices <- c(100, 200, 300, 120, 240, 400, 430, 490, 700, 650)
colors1 <- c("red", "red", "blue", "green","blue", "red", "blue", "green", "green", "red")
size <- c("s", "m", "l", "xl", "l", "s", "m", "xl", "l","m")
city <- c("NY","LA", "DC","NY","LA", "DC","NY","LA", "DC", "NY")
delivery <- c(3, 7, 3, 10, 20, 5, 10, 2, 12,4)
df <- data.frame(year, prices, colors1,size,city, delivery, stringsAsFactors = FALSE)

df$vatprice<- df$prices * 1.2

Это структура моего набора данных. Это выглядит в основном так.

   year prices colors1 size city delivery vatprices
1  2000    100     red    s   NY        3       120
2  2002    200     red    m   LA        7       240
3  2006    300    blue    l   DC        3       360
4  2000    120   green   xl   NY       10       144
5  2004    240    blue    l   LA       20       288
6  2010    400     red    s   DC        5       480
7  2010    430    blue    m   NY       10       516
8  2011    490   green   xl   LA        2       588
9  2020    700   green    l   DC       12       840
10 2006    650     red    m   NY        4       780

Теперь, что я пытаюсь сделать Я хочу создать небольшое блестящее приложение, которое бы показывало следующее:

по оси x диапазон лет (как вы можете видеть, мои годы нечеткие, но я надеюсь, что все еще могу установить их как диапазон)

по оси y: цена или цена

и все эти данные должны быть категоризированы по цвету, размеру или городу.

ui <- basicPage(
  sidebarPanel(
    sliderInput("range", "Year:",min = 1990, max = 2040, value = c(2000,2020)),textOutput("SliderText"),
    selectInput("yaxis", "Y Variable", names(df[,c(2,7)]), selected = names(df)[[2]]),
    radioButtons(inputId = "cat", label = "Categorized by:", names(df[,c(3:5)]))
  ), # closing of the sidebar panel
  plotOutput("scatter")

)


# server 

server <- shinyServer(function(input, output){

  my_range <- reactive({
    cbind(input$range[1],input$range[2])
  })
  output$SliderText <- renderText({my_range()})

  output$scatter <- renderPlot({
    ggplot(df, aes(df$year, df$prices)) + 
   geom_point(aes(color = factor(df$size))) + labs(title = "Overview",
                  color = "Legend") + xlab("Year") + ylab("Price") + theme_minimal()

  })})


shinyApp(ui = ui, server = server)

Поэтому, когда я запускаю программу, я в основном уже получаю весь свой пользовательский интерфейс и сам график. Но мне нужно как-то соединить мой набор данных df с сервером, чтобы сделать мое блестящее приложение интерактивным.

Итак, мой вопрос: нужно ли создавать реактивную переменную для каждого из этих столбцов? Или я должен просто создать один реактивный набор данных? Может кто-нибудь показать мне логику, потому что я все еще чувствую себя потерянным.

Я попытался сделать это, как здесь: Как мне подключить мои входы к выходам моего графика но все равно получил ошибку - поэтому я удалил ее и сохранил только мой основной интерфейс и серверную функцию, так как они не показывают никаких ошибок.

Ответы [ 2 ]

0 голосов
/ 11 мая 2019

Я предлагаю другой ответ, я сделал несколько изменений, сначала я вдохновился базовым уроком:

https://shiny.rstudio.com/tutorial/written-tutorial/lesson4/

Во-вторых, я использую aes_string как в:

Лучший способ преобразовать символьные строки в аргументы функции в R / ggplot2?

Мне кажется более естественным то, что я сделал. Во-вторых, я сделал выбор внутри сервера, я не знаю, насколько он эффективен, но думаю, что он понятен. Во-вторых, ваш cbind внутри data.frame вызов плохая идея, потому что вы заставляете каждую переменную иметь одинаковый тип, а это не то, что вам нужно.

year <- c(2000, 2002, 2006, 2000, 2004, 2010, 2010, 2011, 2020, 2006)
Price <- c(100, 200, 300, 120, 240, 400, 430, 490, 700, 650)
colors1 <- c("red", "red", "blue", "green","blue", "red", "blue", "green", "green", "red")
size <- c("s", "m", "l", "xl", "l", "s", "m", "xl", "l","m")
city <- c("NY","LA", "DC","NY","LA", "DC","NY","LA", "DC", "NY")
delivery <- c(3, 7, 3, 10, 20, 5, 10, 2, 12,4)
df <- data.frame(year,
                 Price,
                 colors1,
                 size, city,
                 delivery)

df$Vatprice <- df$Price * 1.2

str(df)

library(shiny)
library(ggplot2)

ui <- fluidPage(
  sidebarPanel(
    sliderInput("range",
                "Year:", min = 1990,
                max = 2040, value = c(2000, 2020)),
    textOutput("SliderText"),
    selectInput("yaxis",
                "Y Variable",
                names(df[,c(2,7)]),
                selected = names(df)[[2]]),
    radioButtons(inputId = "cat",
                 label = "Categorized by:",
                 names(df[,3:5]))
  ),
  mainPanel(
    plotOutput("scatter")
  )
)

server <- function(input, output){

  output$scatter <- renderPlot({

    select_row_year <- df$year %in% input$range[1]:input$range[2]
    y_indices <- which(colnames(df) == input$yaxis)
    color <- which(colnames(df) == input$cat)

    ggplot(df[select_row_year, ], aes_string(x = "year",
                                             y = colnames(df)[y_indices],
                                             color = colnames(df)[color])) + 
      geom_point() +
      labs(title = "Overview", color = "Legend") +
      xlab("Year") + ylab(input$yaxis) + theme_minimal()
  })
  }

Надеюсь, это поможет вам. Я сделал вашу легенду по оси Y интерактивной.

Редактировать 1:

Это то, что вы ищете:

ui <- fluidPage(
  sidebarPanel(
    sliderInput("range",
                "Year:", min = 1990,
                max = 2040, value = c(2000, 2020)),
    textOutput("SliderText"),
    selectInput("yaxis",
                "Y Variable",
                names(df[,c(2,7)]),
                selected = names(df)[[2]]),
    radioButtons(inputId = "cat",
                 label = "Categorized by:",
                 names(df[,3:5])),
    checkboxGroupInput(inputId = "city",
                       label = "No city choice",
                       choices = NULL,
                       selected = NULL)
  ),
  mainPanel(
    plotOutput("scatter")
  )
)

server <- function(input, output, session){
  observe({
    if(input$cat  == "city"){
     updateCheckboxGroupInput(session=session, inputId = "city",
                             label = "Select city",
                             choices = levels(df$city),
                             selected = NULL)
    }
  })

  output$scatter <- renderPlot({
    if(length(input$city) != 0){
      select_row <- df$year %in% input$range[1]:input$range[2] & df$city %in% input$city
    }else{
      select_row <- df$year %in% input$range[1]:input$range[2]
    }
    y_indices <- which(colnames(df) == input$yaxis)
    color <- which(colnames(df) == input$cat)

    ggplot(df[select_row, ], aes_string(x = "year",
                                             y = colnames(df)[y_indices],
                                             color = colnames(df)[color])) + 
      geom_point() +
      labs(title = "Overview", color = "Legend") +
      xlab("Year") + ylab(input$yaxis) + theme_minimal()
  })
  }

shinyApp(ui = ui, server = server)
0 голосов
/ 11 мая 2019

Во-первых, нам нужно получить окончательное значение df с точки зрения диапазона года и имен столбцов в зависимости от того, что ввел пользователь.Затем нам нужно передать эти переменные в ggplot, используя !!sym, так как они будут в строковой форме, т.е. prices будет "prices", а не prices.

library(dplyr)
library(ggplot2)
server <- shinyServer(function(input, output){

  my_range <- reactive({
    cbind(input$range[1],input$range[2])
  })

  df_final <- reactive({
    filter(df, between(year,input$range[1],input$range[2])) %>% 
    select(year,input$yaxis,input$cat) 
  })

  output$SliderText <- renderText({my_range()})

  #Check if filter and select work correctly and as we wanted
  observe(print(str(df_final()))) 

  output$scatter <- renderPlot({
    ggplot(df_final(), aes(year, !!sym(input$yaxis))) + 
      geom_point(aes(color = factor(!!sym(input$cat)))) + labs(title = "Overview",
                                                      color = "Legend") + xlab("Year") + ylab("Price") + theme_minimal()

  })})


shinyApp(ui = ui, server = server)
...