Shiny — изменение переменных на графике на основе пользовательского ввода

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

> linegraphdata
   Year   E_coli Rain_Intensity Water_Temperature Dew_Point  Humidity Wind_Speed Barometric_Pressure Visibility Cloud_Cover
1  2006 181.4173    0.004077910          79.51720  60.08460 0.6747836   8.092537            1015.748   9.108940   0.5146045
2  2007 212.3498    0.005503364          80.36213  60.06608 0.6597432   6.074101            1015.417   9.173431   0.5019472
3  2008 127.0755    0.003195506          77.77268  58.15240 0.6559700   7.855993            1014.482   9.590509   0.5037079
4  2009 151.2129    0.004728056          74.56725  55.57986 0.6704676   6.278484            1014.511   9.389780   0.5461991
5  2010 142.9604    0.005628907          80.73180  61.37344 0.6662863   6.263983            1014.919   9.536397   0.4672130
6  2011 121.5559    0.005370608          79.44271  60.18298 0.6682699   6.879726            1013.199   9.467782   0.4891249
7  2012 126.4385    0.002568511          80.99142  57.04450 0.5765744   7.416897            1014.416   9.767905   0.3841238
8  2013 142.2380    0.004249872          76.72413  58.13510 0.6703193   7.058155            1015.610   9.451731   0.4211622
9  2014 139.4780    0.006628609          74.93213  58.53608 0.7117897   6.342423            1014.847   9.318628   0.3082917
10 2015 127.3011    0.004109462          75.38712  58.15503 0.7069821   7.058145            1014.534   9.378120   0.3086044
11 2016 123.7218    0.003886790          80.46863  63.90303 0.7176918   6.508438            1014.887   9.648991   0.2763920

Проблема в том, что Shiny принимает предиктор input$ за чистую монету и просто отображает имя переменной вместо списка значений, прикрепленных к этому имени переменной. Он не распознает, что выбранное имя переменной связано с фреймом данных, содержащим значения.

Примечание. Я хочу, чтобы первый график был статическим. Я хочу изменить только второй график.

Вот как приложение выглядит во время работы: Статическое изображение приложения

Вот мой код приложения:

library(shiny)
library(ggplot2)
library(gridExtra)

linegraphdata = read.csv("linegraphdata.csv")

predictor_options <-
  c(
    "Rain_Intensity",
    "Water_Temperature",
    "Dew_Point",
    "Humidity",
    "Wind_Speed",
    "Barometric_Pressure",
    "Visibility",
    "Cloud_Cover"
  )

ui <- fluidPage(fluidRow(
  column(12, offset = 0, tags$h1("Pick a Predictor:")),
  column(
    12,
    offset = 0,
    tags$h4(
      "Which elements of the environment trend with ",
      tags$i("E. coli"),
      " levels? Look for
      the predictor whose line graph peaks and valleys with the average",
      tags$i("E. coli"),
      "levels. "
    )
  ),
  column(4, offset = 0,
         ########################## HERE IS RELEVANT CODE:
         wellPanel(
           selectInput("predictor", "Select a Predictor", choices = predictor_options)
         )),
  column(10,
         plotOutput("graph3"))
))

server <- function(input, output) {
  observeEvent(input$predictor, {
    plot1 <-
      ggplot(data = linegraphdata, aes(x = Year, y = E_coli)) + geom_line() + theme_bw()
    ########################## HERE IS RELEVANT CODE:
    plot2 <-
      ggplot(data = linegraphdata, aes(x = Year, y = input$predictor)) + geom_line() + theme_bw()
    output$graph3 <- renderPlot({
      grid.arrange(plot1, plot2, ncol = 1)
    })
  })
}

shinyApp(ui = ui, server = server)

person Renel Chesak    schedule 11.03.2017    source источник


Ответы (2)


Я нашел ответ! Мне просто нужно было добавить несколько строк, которые связывают ввод с фреймом данных (на стороне сервера). Я сохранил ввод в функцию reactive() и избавился от функцииObservEvent().

server <- function(input, output) {

  data <- reactive({
if ( "Rain_Intensity" %in% input$predictor) return(linegraphdata$Rain_Intensity)
if ( "Water_Temperature" %in% input$predictor) return(linegraphdata$Water_Temperature)
if ( "Dew_Point" %in% input$predictor) return(linegraphdata$Dew_Point)
if ( "Humidity" %in% input$predictor) return(linegraphdata$Humidity)
if ( "Wind_Speed" %in% input$predictor) return(linegraphdata$Wind_Speed)
if ( "Barometric_Pressure" %in% input$predictor) return(linegraphdata$Barometric_Pressure)
if ( "Visibility" %in% input$predictor) return(linegraphdata$Visibility)
if ( "Cloud_Cover" %in% input$predictor) return(linegraphdata$Cloud_Cover)

  })
plot1 <- ggplot(data= linegraphdata, aes(x=Year, y=E_coli)) + geom_line() + theme_bw()
plot2 <- ggplot(data = linegraphdata, aes(x=Year, y=data())) + geom_line() + theme_bw()
output$graph3 <- renderPlot({grid.arrange(plot1, plot2, ncol=1)})

}
person Renel Chesak    schedule 12.03.2017

Если ваши значения input$predictor точно соответствуют именам столбцов вашего linegraphdata data.frame, вы также можете использовать aes_string из ggplot (чтобы использовать строки или имена/вызовы в кавычках для определения эстетических сопоставлений):

plot2 <- ggplot(data = linegraphdata, aes_string(x = "Year", y = input$predictor)) + geom_line() + theme_bw()

Таким образом, вам не нужна реактивная функция с несколькими операторами if.

person Kristoffer Winther Balling    schedule 12.03.2017
comment
Когда я запускаю это, я получаю следующую ошибку: Предупреждение: ошибка в aes_string: объект «Год» не найден Трассировка стека (сначала самая внутренняя): 46: aes_string 45: наследует 44: ggplot.data.frame 43: ggplot 42: сервер [ C:/Users/Renel/Documents/Fake Desktop/App/sampleapp.R#49] 1: Ошибка runApp в aes_string(x = Year, y = datainput$predictor): объект «Год» не найден - person Renel Chesak; 13.03.2017
comment
Вам нужны кавычки вокруг года как в году - у вас есть это? - person Kristoffer Winther Balling; 13.03.2017
comment
Да, это сработало! Благодарю вас! Однако вам все еще нужна реактивная функция. - person Renel Chesak; 14.03.2017